Adobe Flex 3 Help

Dispatching custom events

Flex defines many of the most common events, such as the click event for the Button control; however, your application may require that you create events. In your custom Flex components, you can dispatch any of the predefined events inherited by the component from its superclass, and dispatch new events that you define within the component.

To dispatch a new event from your custom component, you must do the following:

  1. (Optional) Create a subclass from the flash.events.Event class to create an event class that describes the event object. For more information, see Creating a subclass from the Event class.
  2. (Optional) Use the [Event] metadata tag to make the event public so that the MXML compiler recognizes it. For more information, see Using the Event metadata tag.
  3. Dispatch the event using the dispatchEvent() method. For more information, see Dispatching an event.

Creating a subclass from the Event class

All events use an event object to transmit information about the event to the event listener, where the base class for all event objects is the flash.events.Event class. When you define a custom event, you can dispatch an event object of the Event type, or you can create a subclass of the Event class to dispatch an event object of a different type. You typically create a subclass of the Event class when your event requires you to add information to the event object, such as a new property to hold information that the event listener requires.

For example, the event objects associated with the Flex Tree control include a property named node, which identifies the node of the Tree control associated with the event. To support the node property, the Tree control dispatches event objects of type TreeEvent, a subclass of the Event class.

Within your subclass of the Event class, you can add properties, add methods, set the value of an inherited property, or override methods inherited from the Event class. For example, you might want to set the bubbles property to true to override the default setting of false, which is inherited from the Event class.

You are required to override the Event.clone() method in your subclass. The clone() method returns a cloned copy of the event object by setting the type property and any new properties in the clone. Typically, you define the clone() method to return an event instance created with the new operator.

Suppose that you want to pass information about the state of your component to the event listener as part of the event object. To do so, you create a subclass of the Event class to create an event, EnableChangeEvent, as the following example shows:

package myEvents
{
    //events/myEvents/EnableChangeEvent.as
    import flash.events.Event;

    public class EnableChangeEvent extends Event
    {

        // Public constructor.
        public function EnableChangeEvent(type:String, 
            isEnabled:Boolean=false) {
                // Call the constructor of the superclass.
                super(type);
    
                // Set the new property.
                this.isEnabled = isEnabled;
        }

        // Define static constant.
        public static const ENABLE_CHANGED:String = "enableChanged";

        // Define a public variable to hold the state of the enable property.
        public var isEnabled:Boolean;

        // Override the inherited clone() method.
        override public function clone():Event {
            return new EnableChangeEvent(type, isEnabled);
        }
    }
}

In this example, your custom class defines a public constructor that takes two arguments:

  • A String value that contains the value of the type property of the Event object.
  • An optional Boolean value that contains the state of the component's isEnabled property. By convention, all constructor arguments for class properties, except for the type argument, are optional.

From within the body of your constructor, you call the super() method to initialize the base class properties.

Using the Event metadata tag

You use the [Event] metadata tag to define events dispatched by a component so that the Flex compiler can recognize them as MXML tag attributes in an MXML file. You add the [Event] metadata tag in one of the following locations:

ActionScript components Above the class definition, but within the package definition, so that the events are bound to the class and not a particular member of the class.

MXML components In the <mx:Metadata> tag of an MXML file.

The Event metadata keyword has the following syntax:

[Event(name="eventName", type="package.eventType")]

The eventName argument specifies the name, including the package, of the event. The eventType argument specifies the class that defines the event.

The following example identifies the enableChange event as an event that an ActionScript component can dispatch:

[Event(name="enableChange", type="myEvents.EnableChangeEvent")]
public class MyComponent extends TextArea
{
    ...
}

The following example shows the [Event] metadata tag within the <mx:Metadata> tag of an MXML file:

<?xml version="1.0"?>
<!-- events\myComponents\MyButton.mxml -->

<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" 
    click="dispatchEvent(new EnableChangeEvent('enableChanged'));">

    <mx:Script>
        <![CDATA[
            import myEvents.EnableChangeEvent;
        ]]>
    </mx:Script>

    <mx:Metadata>
        [Event(name="enableChanged", type="myEvents.EnableChangeEvent")]
    </mx:Metadata>
    
</mx:Button>

Once you define the event using the [Event] metadata tag, you can refer to the event in an MXML file, as the following example shows:

<?xml version="1.0"?>
<!-- events/MainEventApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:MyComp="myComponents.*" >

    <mx:Script>
        <![CDATA[
            import myEvents.EnableChangeEvent;

            public function 
                enableChangedListener(eventObj:EnableChangeEvent):void {
                    // Handle event.
            }
        ]]>
    </mx:Script>

    <MyComp:MyButton enableChanged="myTA.text='got event';" />

    <mx:TextArea id="myTA" />

</mx:Application>

The executing SWF file for the previous example is shown below:

If you do not identify an event with the [Event] metadata tag, the compiler generates an error if you try to use the event name in MXML. The metadata for events is inherited from the superclass, however, so you do not need to tag events that are already defined with the [Event] metadata tag in the superclass.

Dispatching an event

You use the dispatchEvent() method to dispatch an event. The dispatchEvent() method has the following signature:

public dispatchEvent(event:Event):Boolean

This method requires an argument of the Event type, which is the event object. The dispatchEvent() method initializes the target property of the event object with a reference to the component dispatching the event.

You can create an event object and dispatch the event in a single statement, as the following example shows:

dispatchEvent(new Event("click")); 

You can also create an event object, initialize it, and then dispatch it, as the following example shows:

var eventObj:EnableChangeEvent = new EnableChangeEvent("enableChange");
eventObj.isEnabled=true;
dispatchEvent(eventObj);

For complete examples that create and dispatch custom events, see Advanced MXML Components and Simple Visual Components in ActionScript.

Creating static constants for the Event.type property

The constructor of an event class typically takes a single required argument that specifies the value of the event object's type property. In the previous section, you passed the string enableChange to the constructor, as the following example shows:

// Define event object, initialize it, then dispatch it. 
var eventObj:EnableChangeEvent = new EnableChangeEvent("enableChange");
dispatchEvent(eventObj);

The Flex compiler does not examine the string passed to the constructor to determine if it is valid. Therefore, the following code compiles, even though enableChangeAgain might not be a valid value for the type property:

var eventObj:EnableChangeEvent = 
    new EnableChangeEvent("enableChangeAgain");

Because the compiler does not check the value of the type property, the only time that your application can determine if enableChangeAgain is valid is at run time.

However, to ensure that the value of the type property is valid at compile time, Flex event classes define static constants for the possible values for the type property. For example, the Flex EffectEvent class defines the following static constant:

// Define static constant for event type.
public static const EFFECT_END:String = "effectEnd";

To create an instance of an EffectEvent class, you use the following constructor:

var eventObj:EffectEvent = new EffectEvent(EffectEvent.EFFECT_END);

If you incorrectly reference the constant in the constructor, the compiler generates a syntax error because it cannot locate the associated constant. For example, the following constructor generates a syntax error at compile time because MY_EFFECT_END is not a predefined constant of the EffectEvent class:

var eventObj:EffectEvent = new EffectEvent(EffectEvent.MY_EFFECT_END);

You can use this technique when you define your event classes. The following example modifies the definition of the EnableChangeEventConst class to include a static constant for the type property:

package myEvents
{
    //events/myEvents/EnableChangeEventConst.as
    import flash.events.Event;

    public class EnableChangeEventConst extends Event
    {   
        // Public constructor. 
        public function EnableChangeEventConst(type:String, 
            isEnabled:Boolean=false) {
                // Call the constructor of the superclass.
                super(type);
                
                // Set the new property.
                this.isEnabled = isEnabled;
        }

        // Define static constant.
        public static const ENABLE_CHANGED:String = "myEnable";
            
        // Define a public variable to hold the state of the enable property.
        public var isEnabled:Boolean;

        // Override the inherited clone() method. 
        override public function clone():Event {
            return new EnableChangeEvent(type, isEnabled);
        }
    }
}

Now you create an instance of the class by using the static constant, as the following example shows for the MyButtonConst custom component:

<?xml version="1.0"?>
<!-- events\myComponents\MyButtonConst.mxml -->

<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" 
    click="dispatchEvent(new EnableChangeEventConst(EnableChangeEventConst.ENABLE_CHANGED));">

    <mx:Script>
        <![CDATA[
            import myEvents.EnableChangeEventConst;
        ]]>
    </mx:Script>

    <mx:Metadata>
        [Event(name="myEnable", type="myEvents.EnableChangeEventConst")]
    </mx:Metadata>
    
</mx:Button>

This technique does not preclude you from passing a string to the constructor.