Java 1.1 events.


Events "occur" when the user manipulates the GUI of an applet or an application. There are three kinds of objects that interact in event handling.


(1) an event generator, such as a Button or Menu.
(2) an event object which carries information about the event
(3) an event listener (handler) that is informed when the event occurs and which executes code to handle the event.


When an event (like a mousedown in a button) occurs, the event generator (button) creates an event object (in this case an ActionEvent) and passes it as a parameter to a function call made on each of its listeners. A generator can have several listeners. In this case the method (function) is actionPerformed.


The event object has information in it about when the event occurred, where the mouse was at the time, and the state of the keyboard at the time. It also has a reference to the source (the generator of the event).


In the Java1.1 model, a generator can have several listeners, and each will be informed when the generator generates an event. But the listeners must register with the generator.


There are several different kinds of event objects (ActionEvent, MouseEvent...) and several different kinds of listeners (ActionListener, MouseListener...). If a component can generate a certain kind of event it will register listeners of the appropriate kind. Buttons generate only ActionEvents and register only ActionListeners. For example


Button stopButton = new Button("Stop"); // create a button
ActionListener stopListener = new StopListener(); // create a listener of a user defined type
stopButton.addActionListener(stopListener); // register the listener.


The programmer will also need to create the StopListener class, by implementing the interface ActionListener and its single required method -- and maybe a constructor if needed.


class StopListener implements ActionListener
{

public void actionPerformed(ActionEvent e)
{ ... whatever should be done when the stop button is pushed.
}

}


If the listener doesn't need to be used for anything except handling the event, we can shorten the creation fragment to:


Button stopButton = new Button("Stop"); // create a button
stopButton.addActionListener(new StopListener()); // register a new listener.


Now, whenever that button is pushed, the actionPerformed method of each of its registered listeners will be called and passed an appropriate ActionEvent object.


WARNING. Some of the books that you read will try to short circuit this even more, by making the Applet class itself implement the ActionListener interface. The rationale is that you need to write the Applet class anyway and so all you need to do is let the Applet be a listener for all events that its parts generate. Thus if the applet contains a button, you might see:


class MyApplet extends Applet implements ActionListener // WARNING POOR PRACTICE
{ .... other Applet code, like paint...

public void actionPerformed(ActionEvent e)
{ ... whatever should be done when the stop button is pushed.
}


public void init() // the Applet's required init method
{

...
Button stopButton = new Button("Stop"); // create a button
stopButton.addActionListener(this); // register the Applet itself as listener.

}

}


This is a TERRIBLE way to build code. First it gives the Applet too much to do and is therefore not a good OOP design. Secondly, if you have more than one generator of ActionEvents, then the single actionPerformed is going to have to switch on the source to determine which object generated the event so it knows what to do. This testing will only slow your program down and make it harder to maintain. You will read code like this, BUT DO NOT WRITE IT.


Each event generator should have its own specially created listeners. You should share listeners (one listener for two or more generators) when the logic of the program requires exactly the same action to be taken when the generators are manipulated. This is often the case with a Button and a TextField. They both generate ActionEvents, the button when it is pressed and the Field when the enter key is pressed while the user is typing into it. You sometimes want the button to send the string entered into the text field to some other place in the program (or over the net). By giving the TextField the same action listener as the button, then the same thing will occur if the user simply types and then hits enter, rather than pressing the button.


Events are discussed at length in the Nutshell book, starting on page 150. There are many examples in my GUI tutorial. Also see the paper on Java Event Patterns.