Creating Event Dispatchers


Dispatchers (also known as subjects or targets) are the source of events. These are the objects that fire events. Earlier in this chapter, you saw how to listen for events. Many classes are already capable of dispatching events. However, now we'll look at how to create custom classes that dispatch events.

Understanding Event Objects

All events use event objects. In the following sections, we'll look at how to dispatch events, but first we need to look at how to create an event object.

All event objects must be instances of the flash.events.Event class (or one of its subclasses). Event objects have properties that store information about the event and methods for manipulating the event.

The simplest way to create an event object is to use the constructor of the Event class or one of its subclasses in a new statement. The constructor requires that you pass it a string indicating the event type. The following example creates a new event object for a change event:

var event:Event = new Event(Event.CHANGE);


Often it is easiest and most effective to use an existing event type (Event, MouseEvent, and so on) when possible. However, when that's not possible, you can create a custom event type by subclassing Event. The following is an example of a custom event that extends the Event class:

package {    import flash.events.Event;    public class CustomEvent extends Event {       private var _customData:Object;       public function customData(value:Object):void {          _customData = value;       }        public function get customData():Object {          return _customData;       }       public function CustomEvent(type:String, bubbles:Boolean = false,  cancelable:Boolean = false) {          super(type, bubbles, cancelable);        }    } }


Understanding Event Target Properties

Events have both a target and a currentTarget property. This is relevant when an event is being dispatched into the event flow. It tells us the difference between the object we registered with and the object that dispatched the event. The target is the object that originates the event, while the currentTarget is the object with which you registered the listener. During the target phase, those two properties reference the same object. However, if you get an event during the capture or bubble phase, the two properties are different.

Default Behavior of Events

When most events are fired, the responses to those events are defined in the listeners. But in some cases, the responses are so common and predictable that there are default behaviors that occur inside Flash Player. A good example of this is the use case of a user typing in a text field. The default behavior is that the keystrokes fire events that populate the text field with the corresponding characters. However, there may be times when you don't want this default behavior to happen. To stop the default behavior, you simply call the preventDefault() method of the event object. You can check the status of this behavior by calling the isDefaultPrevented() method. Only events with the cancelable property set to true can be canceled.

Stopping Propagation

In some cases, you might want to stop the event flow dead in its tracks. To accomplish this, you use the stopPropagation() or stopImmediatePropogation() method of the event object. The methods are nearly identical and differ only in regards to when the stop is executed. If you call stopPropagation(), the event is not allowed to continue up the display list, but the currentTarget is allowed to finish dispatching the event to its listeners. The stopImmediatePropogation() method stops the event flow completely, and the currentTarget is not allowed to finish.

Dispatching Events Through Inheritance

The flash.events.EventDispatcher class is at the heart of the event model in ActionScript 3.0. All native Flash Player classes that dispatch events inherit from Eventdispatcher. This is the simplest and most common way to add event dispatching functionality to a class. You can do this directly by creating a class that extends Eventdispatcher. Optionally, because MovieClip, Sprite, and many other core classes already extend Eventdispatcher, you can inherit the event functionality indirectly by extending those classes as well.

The Eventdispatcher class defines the behavior that adds, queues, and removes event listeners. It also enables the dispatcher to actually dispatch the event to the listeners. We've already seen the behavior for adding and removing events using addEventListener() and removeEventListener(). Now we'll look at how to actually dispatch events.

The dispatchEvent() method is a method of EvenTDispatcher, and it is what triggers an event to be broadcast. When you extend Eventdispatcher, you can call dispatchEvent() within the class.

Caution

Although the dispatchEvent() method is public, it's a good idea to leave event dispatching up to the subject objects. Objects triggering events to be dispatched from other subject objects can lead to un-maintainable code that is difficult for other developers to read. Subjects should always be responsible for dispatching their own events.


The only parameter you need to pass into the dispatchEvent() method is an Event object. We'll talk more about Event objects and their behavior later in this chapter. However, here is a basic example:

dispatchEvent(new Event(Event.CHANGE));


This example dispatches a change event to all listeners that are currently registered to receive notifications for change events for instances of the class within which the dispatchEvent() method appears.

The IEventDispatcher Interface

ActionScript 3.0 supports only single inheritance. This means that if you're already extending a class that doesn't itself extend the Eventdispatcher class, you must find another way to access the event dispatching functionality. For this reason, Flash Player includes an IEventDispatcher interface. By programming to this interface, you can get the EvenTDispatcher functionality into your class through composition instead of through inheritance. The following is an example of how you'd implement the IEventDispatcher interface:

package {    import flash.events.Event;    import flash.events.IEventDispatcher;    import flash.events.EventDispatcher;    public class Dispatcher implements IEventDispatcher {       private var eventDispatcher:EventDispatcher;       public function Dispatcher() {          eventDispatcher = new EventDispatcher(this);       }       public function addEventListener(type:String, listener:Function,  useCapture:Boolean=false, priority:int=0.0, useWeakReference:Boolean=false):void {          eventDispatcher.addEventListener(type, listener, useCapture, priority,   useWeakReference);       }       public function dispatchEvent(event:Event):Boolean {          return eventDispatcher.dispatchEvent(event);       }       public function hasEventListener(type:String):Boolean {          return eventDispatcher.hasEventListener(type);       }       public function removeEventListener(type:String, listener:Function, useCapture: Boolean=false):void {          eventDispatcher.removeEventListener(type, listener, useCapture);       }       public function willTrigger(type:String):Boolean {          return eventDispatcher.willTrigger(type);       }    } }


Passing a target reference into the Eventdispather constructor is necessary when using composition. The reference tells the EvenTDispatcher which object to use as the target for events dispatched by your class. This is not necessary for classes that extend Eventdispatcher.




Advanced ActionScript 3 with Design Patterns
Advanced ActionScript 3 with Design Patterns
ISBN: 0321426568
EAN: 2147483647
Year: 2004
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net