Events, Event Sources,
and Event Listeners
In the applications that you
have written so far, user input was under control of the program. The
program asked the user for input in a specific order. For example, a program
might ask the user to supply first a name, then a dollar amount. But the
programs that you use every day on your computer don't work like that. In a
program with a modern graphical user interface, the user is in control.
The user can use both the mouse and the keyboard and can manipulate many parts
of the user interface in any desired order. For example, the user can enter
information into text fields, pull down menus, click buttons, and drag scroll
bars in any order. The program must react to the user commands, in whatever
order they arrive. Having to deal with many possible inputs in random order is
quite a bit harder than simply forcing the user to supply input in a fixed
order.
In the following sections,
you will learn how to write Java programs that can react to user interface
events, such as button pushes and mouse clicks. The Java windowing toolkit has
a very sophisticated mechanism that allows a program to specify the events in
which it is interested and which objects to notify when one of these events
occurs.
User interface events
include key presses, mouse moves, button clicks, menu selections, and so on.
Whenever the user of a
graphical program types characters or uses the mouse anywhere inside one of the
windows of the program, the Java window manager sends a notification to the
program that an event has occurred. The window manager generates huge
numbers of events. For example, whenever the mouse moves a tiny interval over a
window, a “mouse move” event is generated. Events are also generated when the
user presses a key, clicks a button, or selects a menu item.
Most programs don't want to
be flooded by boring events. For example, when a button is clicked with the
mouse, the mouse moves over the button, then the mouse button is pressed, and
finally the button is released. Rather than receiving lots of irrelevant mouse
events, a program can indicate that it only cares about button clicks, not
about the underlying mouse events. However, if the mouse input is used for
drawing shapes on a virtual canvas, it is necessary to closely track mouse
events.
An event listener belongs
to a class that is provided by the application programmer. Its methods describe
the actions to be taken when an event occurs.
Every program must indicate
which events it needs to receive. It does that by installing event
listener objects. An event listener object belongs to a class that you
define. The methods of your event listener classes contain the instructions
that you want to have executed when the events occur.
To install a listener, you
need to know the event source . The
event source is the user interface component that generates a particular event.
You add an event listener object to the appropriate event sources. Whenever the
event occurs, the event source calls the appropriate methods of all attached
event listeners.
Event sources report on
events. When an event occurs, the event source notifies all event listeners.
Use JButton
components for buttons. Attach an ActionListener to
each button.
This sounds somewhat abstract,
so let's run through an extremely simple program that prints a message whenever
a button is clicked. Button listeners must belong to a class that implements
the ActionListener interface:
public interface ActionListener
{ void actionPerformed(ActionEvent event);}
This particular interface
has a single method, actionPerformed. It is your job
to supply a class whose actionPerformed method
contains the instructions that you want executed whenever the button is
clicked. Here is a very simple example of such a listener class:
ch09/button1/ClickListener.java
1 import java.awt.event.ActionEvent;
2 import java.awt.event.ActionListener;
3
4 /**
5 An action listener that prints a message.
6 */
7 public class ClickListener implements ActionListener
8 {
9 public void actionPerformed(ActionEvent event)
10 {
11 System.out.println(“I was clicked.”);
12 }
13 }
We ignore the event
parameter of the actionPerformed method—it contains additional
details about the event, such as the time at which it occurred.
Once the listener class has
been defined, we need to construct an object of the class and add it to the
button:
ActionListener listener = new ClickListener();
button.addActionListener(listener);
Whenever the button is
clicked, it calls
listener.actionPerformed(event);
As a result, the message is
printed.
You can think of the actionPerformed method as another example of a callback,
similar to the measure method of the Measurer class. The windowing toolkit
calls the actionPerformed method whenever the button
is pressed, whereas the DataSet calls the measure
method whenever it needs to measure an object.
You can test this program
out by opening a console window, starting the ButtonViewer program from that console window, clicking the
button, and watching the messages in the console window (see Figure bellow).
ch09/button1/ButtonViewer.java
1 import java.awt.event.ActionListener;
2 import javax.swing.JButton;
3 import javax.swing.JFrame;
4
5 /**
6 This program demonstrates how to install an action listener.
7 */
8 public class ButtonViewer
9 {
10 public static void main(String[] args)
11 {
12 JFrame frame = new JFrame();
13 JButton button = new JButton(”Click me!”);
14 frame.add(button);
15
16 ActionListener listener = new ClickListener();
17 button.addActionListener(listener);
18
19 frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
20 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21 frame.setVisible(true);
22 }
23
24 private static final int FRAME_WIDTH = 100;
25 private static final int FRAME_HEIGHT = 60;
26 }

|
FIGURE |
Implementing an Action
Listener |
_____________________________________________________________________________________________________________ Applet
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/** This applet lets the user move a rectangle by specifying the x- and y-position of the top left corner.*/public class ButtonApplet extends Applet
{ public ButtonApplet() { // the rectangle that the paint method draws box = new Rectangle(BOX_X, BOX_Y, BOX_WIDTH, BOX_HEIGHT); // the text fields for entering the x- and y-coordinates final JTextField xField = new JTextField(5); final JTextField yField = new JTextField(5); // the button to move the rectangle JButton moveButton = new JButton("Move", new ImageIcon("hand.gif")); class MoveButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { int x = Integer.parseInt(xField.getText()); int y = Integer.parseInt(yField.getText()); box.setLocation(x, y); repaint(); } } ActionListener listener = new MoveButtonListener(); moveButton.addActionListener(listener); // the labels for labeling the text fields JLabel xLabel = new JLabel("x = "); JLabel yLabel = new JLabel("y = "); // the panel for holding the user interface components JPanel panel = new JPanel(); panel.add(xLabel); panel.add(xField); panel.add(yLabel); panel.add(yField); panel.add(moveButton); // the frame for holding the component panel JFrame frame = new JFrame(); frame.setContentPane(panel); frame.pack(); frame.show(); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.draw(box); } private Rectangle box; private static final int BOX_X = 100; private static final int BOX_Y = 100; private static final int BOX_WIDTH = 20; private static final int BOX_HEIGHT = 30;}