13.1 The new event model



In the new event model a component can initiate ("fire") an event. Each type of event is represented by a distinct class. When an event is fired, it is received by one or more "listeners," which act on that event. Thus, the source of an event and the place where the event is handled can be separate.

Each event listener is an object of a class that implements a particular type of listener interface. So as a programmer, all you do is create a listener object and register it with the component that's firing the event. This registration is performed by calling a addXXXListener( ) method in the event-firing component, in which XXX represents the type of event listened for. You can easily know what types of events can be handled by noticing the names of the addListener methods, and if you try to listen for the wrong events you'll find out your mistake at compile time. Java Beans also uses the names of the addListener methods to determine what a Bean can do.

All of your event logic, then, will go inside a listener class. When you create a listener class, the sole restriction is that it must implement the appropriate interface. You can create a global listener class, but this is a situation in which inner classes tend to be quite useful, not only because they provide a logical grouping of your listener classes inside the UI or business logic classes they are serving, but because (as you shall see later) the fact that an inner class object keeps a handle to its parent object provides a nice way to call across class and subsystem boundaries.

A simple example will make this clear. Consider the Button2.java example from earlier in last lesson.

Case Study: Button2New.java

So you can compare the two approaches, the old code is left in as a comment. In init( ), the only change is the addition of the two lines:

addActionListener( ) tells a button which object to activate when the button is pressed. The classes B1 and B2 are inner classes that implement the interface ActionListener. This interface contains a single method actionPerformed( ) (meaning "This is the action that will be performed when the event is fired"). Note that actionPerformed( ) does not take a generic event, but rather a specific type of event, ActionEvent. So you don't need to bother testing and downcasting the argument if you want to extract specific ActionEvent information.

One of the nicest things about actionPerformed( ) is how simple it is. It's just a method that gets called. Compare it to the old action( ) method, in which you must figure out what happened and act appropriately, and also worry about calling the base class version of action( ) and return a value to indicate whether it's been handled. With the new event model you know that all the event-detection logic is taken care of so you don't have to figure that out; you just say what happens and you're done. If you're don't already prefer this approach over the old one, you will soon.


Next Page