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, because you have not yet seen how to implement user interfaces, we 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.

C++ NOTE

As you saw in Chapter 5, Java does have the equivalent of function pointers, namely, Method objects. However, they are difficult to use, slower, and cannot be checked for type safety at compile time. Whenever you would use a function pointer in C++, you should consider using an interface in Java.


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.

Example 6-3 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 in 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.

Example 6-3. TimerTest.java
  1. import java.awt.*;  2. import java.awt.event.*;  3. import java.util.*;  4. import javax.swing.*;  5. import javax.swing.Timer;  6. // to resolve conflict with java.util.Timer  7.  8. public class TimerTest  9. { 10.    public static void main(String[] args) 11.    { 12.       ActionListener listener = new TimePrinter(); 13. 14.       // construct a timer that calls the listener 15.       // once every 10 seconds 16.       Timer t = new Timer(10000, listener); 17.       t.start(); 18. 19.       JOptionPane.showMessageDialog(null, "Quit program?"); 20.       System.exit(0); 21.    } 22. } 23. 24. class TimePrinter implements ActionListener 25. { 26.    public void actionPerformed(ActionEvent event) 27.    { 28.       Date now = new Date(); 29.       System.out.println("At the tone, the time is " + now); 30.       Toolkit.getDefaultToolkit().beep(); 31.    } 32. } 


 javax.swing.JOptionPane 1.2 

  • static void showMessageDialog(Component parent, Object message)

    displays a dialog box with a message prompt and an OK button. The dialog is centered over the parent component. If parent is null, the dialog is centered on the screen.


 javax.swing.Timer 1.2 

  • Timer(int interval, ActionListener listener)

    constructs a timer that notifies listener whenever interval milliseconds have elapsed.

  • void start()

    starts the timer. Once started, the timer calls actionPerformed on its listeners.

  • void stop()

    stops the timer. Once stopped, the timer no longer calls actionPerformed on its listeners.


 javax.awt.Toolkit 1.0 

  • static Toolkit getDefaultToolkit()

    gets the default toolkit. A toolkit contains information about the GUI environment.

  • void beep()

    emits a beep sound.


       
    top



    Core Java 2 Volume I - Fundamentals
    Core Java(TM) 2, Volume I--Fundamentals (7th Edition) (Core Series) (Core Series)
    ISBN: 0131482025
    EAN: 2147483647
    Year: 2003
    Pages: 132

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net