views:

4265

answers:

4

How can I raise an event from a SWF file loaded into a Flex application (using SWFLoader)?

I want to be able to detect

a) when a button is pressed
b) when the animation ends
+2  A: 

You'll need to do 2 things:

  1. Dispatch an event from the loaded swf. Make sure the event bubbles if you sent it from nested views. Bubbling can be set through the bubbles property of the event.
  2. Listen to the event from your main application. I think you should be able to do that on the content property of the SWFLoader instance.

    mySWFLoader.content.addEventListener("myEvent", myEventHandler);
    
Christophe Herreman
A: 

As an adjunct to the answer by Christophe Herreman, and in case you were wondering, here is a way of making your own events...

package yourpackage.events
{
    import flash.events.Event;

    [Event(name="EV_Notify", type="yourpackage.events.EV_Notify")]
    public class EV_Notify extends Event
    {
     public function EV_Notify(bubbles:Boolean=true, cancelable:Boolean=false)
     {
      super("EV_Notify", bubbles, cancelable);
     }

    }
}

I have taken the liberty of setting the default value of bubbles to true and passing the custom event type to the super constructor by default, so you can then just say...

dispatchEvent(new EV_Notify());

In your particular case I doubt there are times when you would not want your event to bubble.

The prefix EV_ on the name is my own convention for events so I can easily find them in the code completion popups, you'll obviously pick your own name.

For the two cases you cite you can either have two events and listen for both of them, or add a property to the event which says what just happened, which is the approach which is taken by controls like Alert...

package yourpackage.events
{
    import flash.events.Event;

    [Event(name="EV_Notify", type="yourpackage.events.EV_Notify")]
    public class EV_Notify extends Event
    {
     public static var BUTTON_PRESSED:int = 1;
     public static var ANIMATION_ENDED:int = 2;

     public var whatHappened:int;

     public function EV_Notify(whatHappened:int, bubbles:Boolean=true, cancelable:Boolean=false)
     {
      this.whatHappened = whatHappened;
      super("EV_Notify", bubbles, cancelable);
     }

    }
}

then you call it as follows...

dispatchEvent(new EV_Notify(EV_NOTIFY.ANIMATION_ENDED));

you can then inspect the whatHappened field in your event handler.

private function handleNotify(ev:EV_Notify):void
{
    if (ev.whatHappened == EV_Notify.ANIMATION_ENDED)
    {
        // do something
    }
    else if (ev.whatHappened == EV_Notify.BUTTON_PRESSED)
    {
        // do something else
    }
    etc...
}

HTH

Simon
The Event metadata tag isn't for event subclasses, but for components. It tells the compiler that the component dispatches an event, so that it knows to expect that event's name as an attribute in MXML.
Theo
+1  A: 

I took a lazier approach for raising the event inside flash

Flex:

<mx:SWFLoader  source="homeanimations/tired.swf"  id="swfTired" complete="swfTiredLoaded(event)" />

private function swfTiredLoaded(event:Event): void {
     mySWFLoader.content.addEventListener("continueClicked", continueClickedHandler);
}

Flash:

dispatchEvent(new Event("continueClicked", true, true));
Simon
@Simon: I want to do something similar now. Should `mySWFLoader` be `swfTired` in the above code?
aip.cd.aish
A: 

I could not make this last approach work (with Flash CS4 and Flex 3). I put the dispatchEvent call in one of the last frames of my Flash animation, but could not pick it up in Flex.

I resorted to a counter variable and incrementing until I reached the known last frame number using the ENTER_FRAME event - which I can pick up using almost the same code.

If I can pick this up, then why can't I pick up a custom event?