< Day Day Up > |
To provide a foundation for delegation event model implementations , we'll create the event package, which contains two classes and an interface, as we saw earlier:
Let's see how those items look in real code. 19.3.1 The EventListenerList ClassThe EventListenerList class stores EventListener objects in an array and defines three methods to manage those objects:
Recall our earlier Chat example, in which the event source was the Chat class. In that example, an instance of the Chat class would create an EventListenerList instance to contain listener objects that implement the ChatListener interface. At event time, the Chat instance would invoke the appropriate event method on all objects in the EventListenerList . Example 19-1 shows the code for the EventListenerList class. Example 19-1. The EventListenerList classimport event.*; /** * Manages a list of objects registered to receive events (i.e., instances * of a class that implements EventListener ). This class is used by an event * source to store its listeners. */ class event.EventListenerList { // The listener objects. private var listeners:Array; /** * Constructor */ public function EventListenerList ( ) { // Create a new array in which to store listeners. listeners = new Array( ); } /** * Adds a listener to the list. * * @param l The listener to add. Must implement EventListener . */ public function addObj (l:EventListener):Boolean { // Search for the specified listener. var len:Number = listeners.length; for (var i:Number = len; --i >= 0; ) { if (listeners[i] == l) { return false; } } // The new listener is not already in the list, so add it. listeners.push(l); return true; } /** * Removes a listener from the list. * * @param l The listener to remove. Must implement EventListener . */ public function removeObj (l:EventListener):Boolean { // Search for the specified listener. var len:Number = listeners.length; for (var i = len; --i >= 0; ) { if (listeners[i] == l) { // We found the listener, so remove it. listeners.splice(i, 1); // Quit looking. return true; } } return false; } /** * Returns the complete list of listeners, used during event notification. */ public function getListeners ( ):Array { // Return a copy of the list, not the list itself. return listeners.slice(0); } } In addition to managing event listeners in an EventListenerList instance, the event source must broadcast an event description to its listeners at event time. The description takes the form of an EventObject subclass. Let's create the EventObject class next . 19.3.2 The EventObject ClassThe EventObject class is the parent of all classes that describe an event. It provides a reference to its event source, which lets event listeners retrieve data from the event source or perform actions on it. Subclasses of EventObject define properties that describe an event and often provide methods to access those properties. The EventObject class defines a single method, getSource( ) , which returns a reference to the event source that created the current EventObject instance. The event source reference is supplied to the EventObject via its constructor. As we described earlier, our chat application's EventObject subclass would be ChatEvent , which would define the properties: messageText , messageSender , oldUserName , and newUserName . Example 19-2 shows the code for the EventObject class. Example 19-2. The EventObject class/** * The base class for an object describing an event. * EventObject instances are passed to event methods defined * by classes that implement EventListener. * Each kind of event should be represented by an EventObject subclass. * * Each EventObject instance stores a reference to its event source , * which is the object that generated the event. */ class event.EventObject { // The source of the event. private var source:Object; /** * Constructor * * @param src The source of the event. */ public function EventObject (src:Object) { source = src; } /** * Returns the source of the event. */ public function getSource ( ):Object { return source; } } In order to receive an event notice (and with it, an EventObject instance), an event listener object must be an instance of a class that implements the appropriate event listener interface. The event source class determines which interface its event listeners must implement. All specific event listener interfaces are subclasses of the generic EventListener interface, described next. 19.3.3 The EventListener InterfaceThe EventListener interface is a so-called marker interface (as explained in Chapter 8). It simply tags a class as being part of the delegation event model structure. Each implementation of the delegation event model must supply an EventListener subinterface listing all methods that can be triggered by the event source. Listener classes wishing to register to receive events from a particular event source must implement that source's corresponding EventListener subinterface. For example, suppose the class OrderForm is an event source and the class FormValidator is an event listener. In order to receive events from OrderForm , the FormValidator class would have to implement, say, FormListener . The FormListener interface would extend EventListener and define the OrderForm 's events ”perhaps onFormSubmit( ) and onFormReset( ) . Example 19-3 shows the code for the EventListener interface. Example 19-3. The EventListener interface/** * This is a marker interface that marks a class as an event * listener. All event listener interfaces should extend this interface. */ interface event.EventListener { } |
< Day Day Up > |