Manually dispatching events

You can manually dispatch events using a component instance’s dispatchEvent() method. All components that extend UIComponent have this method. The method is inherited from the EventDispatcher class, which UIComponent extends.

The syntax for the dispatchEvent() method is as follows:

objectInstance.dispatchEvent(event:Event):Boolean

When dispatching an event, you must create a new Event object. The syntax for the Event object constructor is as follows:

Event(event_type:String, bubbles:Boolean, cancelable:Boolean)

The event_type parameter is the type property of the Event object. The bubbles and cancelable parameters are optional and both default to false. For information on bubbling and capturing, see Event propagation.

You can use the dispatchEvent() method to dispatch any event you want, not just a custom event. You can dispatch a Button control’s click event, even though the user did not click a Button control, as in the following example:

<?xml version="1.0"?>
<!-- events/DispatchEventExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark"
    initialize="createListener(event);">
    
    <fx:Script><![CDATA[
        import mx.controls.Alert;
        private function createListener(e:Event):void {
            b1.addEventListener(MouseEvent.MOUSE_OVER, myEventHandler);
            b1.addEventListener(MouseEvent.CLICK, myClickHandler);
        }

        private function myEventHandler(e:Event):void {
            var result:Boolean = b1.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));           
        }

        private function myClickHandler(e:Event):void {
            Alert.show("The event dispatched by the MOUSE_OVER was of type '" + e.type + "'.");
        }
    ]]></fx:Script>

    <s:Button id="b1" label="Click Me"/>

</s:Application>

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

You can also manually dispatch an event in an MXML tag. In the following example, moving the mouse pointer over the button triggers the button’s click event:

<?xml version="1.0"?>
<!-- events/DispatchEventExampleInline.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark"
    initialize="createListener(event);">

    <fx:Script>
        <![CDATA[
        import mx.controls.Alert;

        private function createListener(e:Event):void {
            b1.addEventListener(MouseEvent.CLICK, myClickHandler);
        }

        private function myClickHandler(e:Event):void {
            Alert.show("The event dispatched by the MOUSE_OVER was of type '" + e.type + "'.");
        }
        ]]>
    </fx:Script>

    <s:Button id="b1" 
        label="Click Me" 
        mouseOver="b1.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));"
    />

</s:Application>

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

Your application is not required to handle the newly dispatched event. If you trigger an event that has no listeners, Flex ignores the event.

You can set properties of the Event object in ActionScript, but you cannot add new properties because the object is not dynamic. The following example intercepts a click event. It then creates a new MouseEvent object and dispatches it as a doubleClick event. In addition, it sets the value of the shiftKey property of the MouseEvent object to true, to simulate a Shift-click on the keyboard.

<?xml version="1.0"?>
<!-- events/DispatchCustomizedEvent.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark"
    creationComplete="addListeners()">
    
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <fx:Script><![CDATA[
        private function customLogEvent(e:MouseEvent):void {
            l1.text = String(e.currentTarget.id);
            l2.text = String(e.type);
            l3.text = String(e.shiftKey);

            // Remove current listener to avoid recursion.
            e.currentTarget.removeEventListener("doubleClick", customLogEvent);
        }

        private function handleEvent(e:MouseEvent):void {
            // Add new handler for custom event about to be dispatched.
            e.currentTarget.addEventListener("doubleClick", customLogEvent);

            // Create new event object.
            var mev:MouseEvent = new MouseEvent("doubleClick");

            // Customize event object.
            mev.shiftKey = true;

            // Dispatch custom event.
            e.currentTarget.dispatchEvent(mev);
        }

        private function addListeners():void {
            b1.addEventListener("click",handleEvent);
            b2.addEventListener("click",handleEvent);
        }

    ]]></fx:Script>

        <s:Button id="b1" label="Click Me (b1)"/>
        <s:Button id="b2" label="Click Me (b2)"/>
        
        <s:Form>
            <s:FormItem label="Current Target:">
                <s:Label id="l1"/>
            </s:FormItem>
            <s:FormItem label="Event Type:">
                <s:Label id="l2"/>
            </s:FormItem>
            <s:FormItem label="Shift Key Pressed:">
                <s:Label id="l3"/>
            </s:FormItem>
        </s:Form>

</s:Application>

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

If you want to add custom properties to an Event object, you must extend the Event object and define the new properties in your own custom class. You can then manually dispatch your custom events with the dispatchEvent() method, as you would any event.

If you create a custom ActionScript class that dispatches its own events but does not extend UIComponent, you can extend the flash.events.EventDispatcher class to get access to the addEventListener(), removeEventListener(), and dispatchEvent() methods.

To make your code more efficient, you can check to see if the intended target of a dispatched event is listening for the event. If it is not, then there is no reason to dispatch the event. This is especially true if the event bubbles because that means many calls will be made by the system while it searches for a target. You can check by using the hasEventListner() and willTrigger() methods. Peter deHaan has a blog post on using these methods.