There are about half-dozen different types of event
listeners. The most common is the
ActionListener
, used by push buttons, text fields,
and certain other components to indicate that the user has performed
a high-level action such as activating a push button or pressing
Return in a text field. The paradigm (shown in Figure 13-3) is that you create a
Listener
object, register it with the event source
(such as the push button) and wait. Later, when and if the user
pushes the button, the button will call your
Listener
.
Here’s some simple code in which pushing a button causes the
program to print a
friendly message. This
program is an applet (see Section 17.3), so it can use the showStatus( )
method to print its text:
import java.applet.*; import java.awt.*; import java.awt.event.*; /** Demonstrate use of Button */ public class ButtonDemo extends Applet implements ActionListener { Button b1; public ButtonDemo( ) { add(b1 = new Button("A button")); b1.addActionListener(this); } public void actionPerformed(ActionEvent event) { showStatus("Thanks for pushing my button!"); } }
This version does not use an inner class to handle the events, but
does so itself by directly implementing the
ActionListener
interface. This works for small
programs, but as an application grows, quickly becomes unserviceable;
how do you sort out which button was pressed? To solve this problem,
we normally use an
inner class as the action handler, and
have a different class for each button. First, let’s write the
previous code with two buttons, so you’ll see what I mean:
import java.applet.*; import java.awt.*; import java.awt.event.*; /** Demonstrate use of two buttons, using a single ActionListener, * being the class itself. */ public class ButtonDemo2a extends Applet implements ActionListener { Button b1, b2; public void init( ) { add(b1 = new Button("A button")); b1.addActionListener(this); add(b2 = new Button("Another button")); b2.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource( ) == b1) showStatus("Thanks for pushing my first button!"); else showStatus("Thanks for pushing my second button!"); } }
Now here it is using a member inner class , that is, a class that is a named part of another class:
import java.applet.*; import java.awt.*; import java.awt.event.*; /** Demonstrate use of two buttons, using a single ActionListener * made of a named inner class */ public class ButtonDemo2b extends Applet { Button b1, b2; ActionListener handler = new ButtonHandler( ); public void init( ) { add(b1 = new Button("A button")); b1.addActionListener(handler); add(b2 = new Button("Another button")); b2.addActionListener(handler); } class ButtonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getSource( ) == b1) showStatus("Thanks for pushing my first button!"); else showStatus("Thanks for pushing my second button!"); } } }
Note that merely breaking the action handling code into its own class doesn’t really contribute much to readability. But there is a way to use inner classes that does promote readability and maintainability. We create an inner class (see Section 8.7) for each event source: each button, each menu item, and so on. Sounds like a lot of work. And it would be, if you used the previous method. But there is a shorter way, using anonymous inner classes, described next.
3.145.174.253