Event Programming Fundamentals

Let's adopt a bit of a myth when thinking about objects. Let's think of objects as if they were people. Each object (person) will have three capabilities. First a memory capability. This is represented by the instance variables of the object. Second, the ability to communicate by asking other objects (people) for services. Third, the ability to carry out some task or perform some service. This service is often the suplying of some information. Carrying out the service may require communicating with other objects to get them to provide their service and obtain the required information. Getting a request for service may also require remembering something (storing something in the object's memory).

Sometimes we want one object to perform its task as soon as something special happens in another object. This "something special" is called an event. An example of an event is the user of a computer pressing a button on the screen. Another is the typing of any key on the keyboard. Another kind of event is information arriving at a communication port on a server, indicating a communication from a client, such as when the text typed in a chat room application arrives at the server.

The object in which the event actually occurs is called the event generator. This might be a button on the screen. The event occurs when the user presses the button.

The object that will perform the task when the event occurs is called the event handler. There may actually be several event handlers for a given event. Each event handler may need to do something different when the event occurs. How do the event handlers find out that the event has occured so that they can carry out the proper task?

An object (person) that generates events can perform a "registration service" for its event handlers. An event handler can ask an event generator to simply inform it when the event occurs. This request is called a registration. The event generator remembers who all of the registered event handlers are.

In the following picture the man acts as an event handler and the woman as a generator of time events.

The woman remembers who has registered for the "time service," namely the man.

When the event occurs (and each time it occurs), the event generator sends a message to each of its event handlers saying that the event of interest occured. The event handler can then carry out the task.

In our little scenario, after a while the event (becoming 9 o'clock) occurs. Then we have:

 

The man then carries out the task required at 9 o'clock, perhaps putting the chess set away and leaving, perhaps proposing marriage.

Here is a somewhat more technical picture of the time flow in such a system. Time flows vertically downward. The arrows indicate messages. Each vertical line represents a single object that sends or receives a message. There is no time scale. In the above pictures the event handler asks to have itself registered, but in general there is no need for this restriction. In fact any object can register an event handler. This would be like a relative of the woman asking that the man be informed when 9 o'clock occurs, rather than the man asking for himself. In either case the man is the handler.

 

Event Sequence Figure

 

When programming in Java, the event generators are for the most part already part of the Java system and don't need to be modified. The programmer developing an applet or application will write event handlers, however. The programmer will also need to register the handler with the appropriate event generator.

In java there are several ways to register, depending on what kind of event generator we have. One of the most common is the Java Button. Buttons generate ActionEvents. There are several other kinds of events generated by other component types in Java. An event handler is technically called a listener in Java. A listener is registered with a button, by some object sending it the addActionListener message, with a parameter indicating who the listener (handler) is going to be. The button remembers who is registered. This is done automatically by code in the Java libraries.

Later, when the event occurs, the button informs the listeners (there may be several) that the event occured by sending the actionPerformed message to each of the listeners. This is also done automatically by Java library code. To be a listener you must have such a message implemented, of course. It is in this method that the listener carries out the task that is supposed to be done when the event occurs.

The action performed message has a paremeter that gives information about the event that occured. For action events this includes where the mouse was clicked and other information.

Here is an example of what the Java code might look like in a simple case.

...
Button myButton = new Button("Click Me");
myButton.addActionListener(new Clicker()); // register
...

class Clicker implements ActionListener
{	public void actionPerformed(ActionEvent e)
	{	System.out.println("Click Me was clicked."); // perfrom task
	}
}

An object becomes an action listener (handler for action events) by implementing the ActionListener interface and therefore the required actionPerformed public method.

Here is our picture redrawn to show the names of the Java messages. Note that we didn't give the listener a name in the avove code. Nor do we have a name for the object in which the addActionListener code appears. We use generic names for these two objects.

 

 

Also note that if the event occurs several times, the listener will be informed each time it occurs.

For more on events see the paper on event handling patterns.

Chapter 7 of Java in a Nutshell has a complete discussion of Java Events. This discussion tells which components generate events and what kind of events each can generate. It also gives the interfaces that handlers much implement in order to handle those kinds of events.

April 15, 2000