- 6.1. Interfaces
- 6.2. Object Cloning
- 6.3. Interfaces and Callbacks
- 6.4. Inner Classes
- 6.5. Proxies
6.3. Interfaces and Callbacks
A common pattern in programming is the callback pattern. In this pattern, you want to specify the action that should occur whenever a particular event happens. For example, you may want a particular action to occur when a button is clicked or a menu item is selected. However, as you have not yet seen how to implement user interfaces, we will consider a similar but simpler situation.
The javax.swing package contains a Timer class that is useful if you want to be notified whenever a time interval has elapsed. For example, if a part of your program contains a clock, then you can ask to be notified every second so that you can update the clock face.
When you construct a timer, you set the time interval and you tell it what it should do whenever the time interval has elapsed.
How do you tell the timer what it should do? In many programming languages, you supply the name of a function that the timer should call periodically. However, the classes in the Java standard library take an object-oriented approach. You pass an object of some class. The timer then calls one of the methods on that object. Passing an object is more flexible than passing a function because the object can carry additional information.
Of course, the timer needs to know what method to call. The timer requires that you specify an object of a class that implements the ActionListener interface of the java.awt.event package. Here is that interface:
public interface ActionListener { void actionPerformed(ActionEvent event); }
The timer calls the actionPerformed method when the time interval has expired.
Suppose you want to print a message “At the tone, the time is . . .”, followed by a beep, once every 10 seconds. You would define a class that implements the ActionListener interface. You would then place whatever statements you want to have executed inside the actionPerformed method.
class TimePrinter implements ActionListener { public void actionPerformed(ActionEvent event) { Date now = new Date(); System.out.println("At the tone, the time is " + now); Toolkit.getDefaultToolkit().beep(); } }
Note the ActionEvent parameter of the actionPerformed method. This parameter gives information about the event, such as the source object that generated it—see Chapter 8 for more information. However, detailed information about the event is not important in this program, and you can safely ignore the parameter.
Next, you construct an object of this class and pass it to the Timer constructor.
ActionListener listener = new TimePrinter(); Timer t = new Timer(10000, listener);
The first parameter of the Timer constructor is the time interval that must elapse between notifications, measured in milliseconds. We want to be notified every 10 seconds. The second parameter is the listener object.
Finally, you start the timer.
t.start();
Every 10 seconds, a message like
At the tone, the time is Thu Apr 13 23:29:08 PDT 2000
is displayed, followed by a beep.
Listing 6.5 puts the timer and its action listener to work. After the timer is started, the program puts up a message dialog and waits for the user to click the Ok button to stop. While the program waits for the user, the current time is displayed at 10-second intervals.
Be patient when running the program. The “Quit program?” dialog box appears right away, but the first timer message is displayed after 10 seconds.
Note that the program imports the javax.swing.Timer class by name, in addition to importing javax.swing.* and java.util.*. This breaks the ambiguity between javax.swing.Timer and java.util.Timer, an unrelated class for scheduling background tasks.
Listing 6.5. timer/TimerTest.java
1 package timer; 2 /** 3 @version 1.00 2000-04-13 4 @author Cay Horstmann 5 */ 6 7 import java.awt.*; 8 import java.awt.event.*; 9 import java.util.*; 10 import javax.swing.*; 11 import javax.swing.Timer; 12 // to resolve conflict with java.util.Timer 13 14 public class TimerTest 15 { 16 public static void main(String[] args) 17 { 18 ActionListener listener = new TimePrinter(); 19 20 // construct a timer that calls the listener 21 // once every 10 seconds 22 Timer t = new Timer(10000, listener); 23 t.start(); 24 25 JOptionPane.showMessageDialog(null, "Quit program?"); 26 System.exit(0); 27 } 28 } 29 30 class TimePrinter implements ActionListener 31 { 32 public void actionPerformed(ActionEvent event) 33 { 34 Date now = new Date(); 35 System.out.println("At the tone, the time is " + now); 36 Toolkit.getDefaultToolkit().beep(); 37 } 38 }