Adobe Flex 3 Help

Defining multiple listeners for a single event

You can define multiple event handler functions for a single event in two ways. When defining events inside MXML tags, you separate each new handler function with a semicolon. The following example adds the submitForm() and debugMessage() functions as handlers of the click event:

<?xml version="1.0"?>
<!-- events/MultipleEventHandlersInline.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script><![CDATA[
        [Bindable]
        private var s:String = "";
  
        private function submitForm(e:Event):void {
            // Handle event here.
            s += "The submitForm() method was called. ";
        }
        private function debugMessage(e:Event):void {
            // Handle event here.
            s += "The debugMessage() method was called. ";
        }
    ]]></mx:Script>
  
    <mx:Button id="b1" 
        label="Do Both Actions"
        click='submitForm(event); debugMessage(event);' 
    />
    <mx:Label id="l1" text="{s}"/>
    
    <mx:Button id="b2" label="Reset" click="s='';"/>
    
</mx:Application>

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

For events added with the addEventListener() method, you can add any number of handlers with additional calls to the addEventListener() method. Each call adds a handler function that you want to register to the specified object. The following example registers the submitForm() and debugMessage() handler functions with b1's click event:

<?xml version="1.0"?>
<!-- events/MultipleEventHandlersAS.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="createHandlers(event)">
    <mx:Script><![CDATA[
        [Bindable]
        private var s:String = "";

        public function createHandlers(e:Event):void {
            b1.addEventListener(MouseEvent.CLICK, submitForm);
            b1.addEventListener(MouseEvent.CLICK, debugMessage);
        }

        private function submitForm(e:Event):void {
            // Handle event here.
            s += "The submitForm() method was called. ";
            
        }

        private function debugMessage(e:Event):void {
            // Handle event here.
            s += "The debugMessage() method was called. ";            
        }

    ]]></mx:Script>

    <mx:Button id="b1" label="Do Both Actions"/>

    <mx:Label id="l1" text="{s}"/>
    
    <mx:Button id="b2" label="Reset" click="s='';"/>

</mx:Application>

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

You can mix the methods of adding event handlers to any component; alternatively, you can add handlers inline and with the addEventListener() method. The following example adds a click event handler inline for the Button control, which calls the performAction() method. It then conditionally adds a second click handler to call the logAction() method, depending on the state of the CheckBox control.

<?xml version="1.0"?>
<!-- events/ConditionalHandlers.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initApp(event)">
  <mx:Script><![CDATA[
     import mx.controls.Alert;
  
     private function initApp(e:Event):void {
        cb1.addEventListener(MouseEvent.CLICK, handleCheckBoxChange);
        b1.addEventListener(MouseEvent.CLICK, logAction);
     }
  
     private function handleCheckBoxChange(e:Event):void {
        if (cb1.selected) {
           b1.addEventListener(MouseEvent.CLICK, logAction);
           ta1.text += "Added log listener." + "\n";
        } else {
           b1.removeEventListener(MouseEvent.CLICK, logAction);
           ta1.text += "Removed log listener." + "\n";
        }
     }
  
     private function performAction(e:Event):void {
        Alert.show("You performed the action.");
     }
  
     private function logAction(e:Event):void {
        ta1.text += "Action performed: " + e.type + ".\n";
     }
  ]]></mx:Script>
  
  <mx:Button label="Perform Action" id="b1" click="performAction(event)"/>
  <mx:CheckBox id="cb1" label="Log?" selected="true"/>
  <mx:TextArea id="ta1" height="200" width="300"/>

</mx:Application>

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

You can set the order in which event listeners are called by using the priority parameter of the addEventListener() method. You cannot set a priority for a listener function if you added the event listener using MXML inline. For more information on setting priorities, see Event priorities.

Registering a single listener with multiple components

You can register the same listener function with any number of events of the same component, or events of different components. The following example registers a single listener function, submitForm(), with two different buttons:

<?xml version="1.0"?>
<!-- events/OneHandlerTwoComponentsInline.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script><![CDATA[
        import mx.controls.Alert;

        private function submitForm(e:Event):void {
            // Handle event here.
            Alert.show("Current Target: " + e.currentTarget.id);
        }

    ]]></mx:Script>

    <mx:Button id="b1" 
        label="Click Me"
        click="submitForm(event)"
    />

    <mx:Button id="b2" 
        label="Click Me, Too"
        click="submitForm(event)"
    />
</mx:Application>

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

When you use the addEventListener() method to register a single listener to handle the events of multiple components, you must use a separate call to the addEventListener() method for each instance, as the following example shows:

<?xml version="1.0"?>
<!-- events/OneHandlerTwoComponentsAS.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="createHandlers(event)">
    <mx:Script><![CDATA[
        import mx.controls.Alert;

        public function createHandlers(e:Event):void {
            b1.addEventListener(MouseEvent.CLICK, submitForm);
            b2.addEventListener(MouseEvent.CLICK, submitForm);
        }

        private function submitForm(e:Event):void {
            // Handle event here.
            Alert.show("Current Target: " + e.currentTarget.id);
        }
    ]]></mx:Script>

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

    <mx:Button id="b2" label="Click Me, Too"/>

</mx:Application>

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

When doing this, you should add logic to the event listener that processes the type of event. The event target (or object that dispatched the event) is added to the Event object for you. No matter what triggered the event, you can conditionalize the event processing based on the target or type properties of the Event object. Flex adds these two properties to all Event objects.

The following example registers a single listener function (myEventHandler()) to the click event of a Button control and the click event of a CheckBox control. To detect what type of object called the event listener, the listener checks the className property of the target in the Event object in a case statement.

<?xml version="1.0"?>
<!-- events/ConditionalTargetHandler.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
    <mx:Script><![CDATA[
        import mx.controls.Alert;
    
        public function initApp():void {
            button1.addEventListener(MouseEvent.CLICK, myEventHandler);
            cb1.addEventListener(MouseEvent.MOUSE_DOWN, myEventHandler);
        }

        public function myEventHandler(event:Event):void {
            switch (event.currentTarget.className) {
                case "Button":
                    // Process Button click.
                    Alert.show("You clicked the Button control.");
                    break;
                case "CheckBox":
                    // Process CheckBox click.
                    Alert.show("You clicked the CheckBox control.");
                    break;
            }
        }
    ]]></mx:Script>

    <mx:Button label="Click Me" id="button1"/>
    <mx:CheckBox label="Select Me" id="cb1"/>

</mx:Application>

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

Passing additional parameters to listener functions

You can pass additional parameters to listener functions depending on how you add the listeners. If you add a listener with the addEventListener() method, you cannot pass any additional parameters to the listener function, and that listener function can declare only a single argument, the Event object (or one of its subclasses).

For example, the following code throws an error because the clickListener() method expects two arguments:

<mx:Script>
    public function addListeners():void {
        b1.addEventListener(MouseEvent.CLICK,clickListener);
    }
    public function clickListener(e:MouseEvent, a:String):void { ... }
</mx:Script>
<mx:Button id="b1"/>

Because the second parameter of addEventListener() is a function, you cannot specify parameters of that function in the addEventListener() call. So, to pass additional parameters to the listener function, you must define them in the listener function and then call the final method with those parameters. If you define an event listener inline (inside the MXML tag), you can add any number of parameters as long as the listener function's signature agrees with that number of parameters. The following example passes a string and the Event object to the runMove() method:

<?xml version="1.0"?>
<!-- events/MultipleHandlerParametersInline.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script><![CDATA[
     public function runMove(dir:String, e:Event):void {
        if (dir == "up") {
           moveableButton.y = moveableButton.y - 5;
        } else if (dir == "down") {
           moveableButton.y = moveableButton.y + 5;
        } else if (dir == "left") {
           moveableButton.x = moveableButton.x - 5;
        } else if (dir == "right") {
           moveableButton.x = moveableButton.x + 5;
        }
     }
  ]]></mx:Script>

  <mx:Canvas height="100%" width="100%">
     <mx:Button id="moveableButton" 
        label="{moveableButton.x.toString()},{moveableButton.y.toString()}" 
        x="75" 
        y="100" 
        width="80"
     />
  </mx:Canvas>

  <mx:VBox horizontalAlign="center">
     <mx:Button id="b1" 
        label="Up" 
        click='runMove("up",event);' 
        width="75"
     />
        <mx:HBox horizontalAlign="center">
           <mx:Button id="b2" 
            label="Left" 
            click='runMove("left",event);' 
            width="75"
           />
           <mx:Button id="b3" 
            label="Right" 
            click='runMove("right",event);' 
            width="75"
           />
        </mx:HBox>
     <mx:Button id="b4" 
        label="Down" 
        click='runMove("down",event);'
        width="75"
     />
  </mx:VBox>

</mx:Application>

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