FlashCanon Flash and Flex stuff from Jason Fincanon

30Sep/085

Making Flash and Flex talk (Part 2)


As promised in my previous post, here's part 2 of Making Flash and Flex talk. This post is going to be a bit shorter than part 1 since a lot of the code and information is the same. You'll see in the example that the user experience is the same in both this post and part 1. However, by using listeners and a custom event in this example, we lessen the chance for error that could be caused by calling a function directly by name in a child (parent) file.

This example involves a total of 4 files: FF_Talk.mxml, FFTalkEvent.as, ffTalkSwf.swf and, of course ffTalkSwf.fla.
You can view the source code either here or by right-clicking on the example and clicking "View Source". You can also grab the zip containing these files via the download link at the end of this post.

THE CODE:
Let's take a look at the source and break it down just a little.

FLEX SIDE:
As in part 1, I start by declaring the variables flashSaid and mySwfMc. This time however, I also import a new class file named FFTalkEvent which will serve as the means of communication between Flex and Flash in this case. More about FFTalkEvent below.

Actionscript:
  1. import com.fincanon.events.FFTalkEvent;
  2.            
  3. [Bindable]
  4. private var flashSaid:String = "";
  5. private var mySwfMc:MovieClip;

Also just like in part 1, the next thing in the mxml file is the setSwfMc function. This function still casts the content of the SWFLoader as a MovieClip but now it adds an event listener to both the loaded swf and its Flex parent (instead of sending a reference of the Flex parent into the swf).

Actionscript:
  1. private function setSwfMc():void{
  2.     mySwfMc = mySWFLoader.content as MovieClip;
  3.     mySwfMc.addEventListener(FFTalkEvent.TALK_TO_FLEX,listenToFlash);
  4.     this.addEventListener(FFTalkEvent.TALK_TO_FLASH,mySwfMc.listenToFlex);
  5. }

Next are the functions listenToFlash and talkToFlash (you'll also recognize these from part 1). The big difference this time is that we're either listening for or dispatching a new FFTalkEvent instead of making the more "dangerous" move of calling a function directly by name. By NOT calling a function directly by name, some of the possibility for error is removed. In part 1, I was calling function in the child swf... but what if that function wasn't there? The results of that call could end up bringing the user's experience to a grinding halt.

Actionscript:
  1. private function listenToFlash(e:FFTalkEvent):void{
  2.     flashSaid = e.said;
  3. }
  4.            
  5. private function talkToFlash(stringToPass:String):void{
  6.     dispatchEvent(new FFTalkEvent(FFTalkEvent.TALK_TO_FLASH,false,false,stringToPass))
  7. }

As you can see in the source, the rest of the mxml file is simply the text fields, labels, buttons, SWFLoader, etc.

FLASH SIDE:
Again, as in part 1, the code in the child swf is not that far off from the code in the parent mxml. Also, the main difference between this version and the version in Part 1 is the fact that we're importing FFTalkEvent and we're listening for or dispatching new instances of FFTalkEvent.

Actionscript:
  1. import com.fincanon.events.FFTalkEvent;
  2.  
  3. function talkToFlex(me:MouseEvent):void{
  4.     dispatchEvent(new FFTalkEvent(FFTalkEvent.TALK_TO_FLEX, false, false, flashInputTxt.text));
  5. }
  6.  
  7. function listenToFlex(e:FFTalkEvent):void{
  8.     flexSaidTxt.text = e.said;
  9. }
  10.  
  11. talkToFlexBtn.addEventListener(MouseEvent.CLICK,talkToFlex);

FFTalkEvent:
FFTalkEvent in its current state is a simple, straight forward, bare-bones class that extends Event. It contains a couple of constants (TALK_TO_FLEX and TALK_TO_FLASH) and a String var named said. If you notice above, we call the said variable to get the value that was passed from Flex to Flash (or vice-versa).

Actionscript:
  1. package com.fincanon.events{
  2.     import flash.events.Event;
  3.    
  4.     public class FFTalkEvent extends Event{
  5.         public static const TALK_TO_FLEX:String = "TalkToFlex";
  6.         public static const TALK_TO_FLASH:String = "TalkToFlash";
  7.         public var said:String;
  8.        
  9.         public function FFTalkEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, sentString:String="") {
  10.             this.said = sentString;
  11.             super(type, bubbles, cancelable);
  12.         }
  13.     }
  14. }

THE EXAMPLE:

This movie requires Flash Player 9

WHERE TO GO FROM HERE:
Like I said, FFTalkEvent in its current state is a simple, straight forward, bare-bones class. While this example is simply passing a string, you can see where it could very easily be built upon to handle much more complex tasks and I'll most likely take the time to do that in down time between projects. Whether or not I post future versions may depend on how much feedback/interest I see with this version.

DOWNLOAD THE ZIP:
Source files here.

http://flash.fincanon.com/wp-content/plugins/sociofluid/images/digg_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/reddit_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/dzone_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/delicious_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/furl_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/technorati_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/google_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/myspace_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/facebook_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/yahoobuzz_48.png http://flash.fincanon.com/wp-content/plugins/sociofluid/images/twitter_48.png
Comments (5) Trackbacks (0)
  1. This post was a life saver was trying to figure this out…

    Much Appreciated…

    Peace…

  2. This is a nice example, but you still need to know the name of the method in the child SWF. Please glance at line number 4 and the listenToFlex method.

    1.private function setSwfMc():void{
    2. mySwfMc = mySWFLoader.content as MovieClip;
    3. mySwfMc.addEventListener(FFTalkEvent.TALK_TO_FLEX,listenToFlash);
    4. this.addEventListener(FFTalkEvent.TALK_TO_FLASH,mySwfMc.listenToFlex);
    5.}

  3. Thanks Rion, you are correct, but here’s a question:
    If you don’t know the name of the method in the child swf, how would you tell it how to react when the listener is triggered?

    On top of that, if you don’t know the name of the method in the child swf, then you are either not the developer of the child swf or you are not working directly with the developer of the child swf. I would think that being able to load and then control child swfs that you had no part in creating could lead to some serious security issues.

  4. I think the perferct solution is to use just an event name in both applications which are trying to communicate. Let’s say MainApplication trigers “eventA” and that event can be handled in SubApplication, wheras SubAplication triggers “eventB” which can be handled by MainApplication. This way your applications are not tightly coupled.

    I don’t see serious security issue here because:
    - MainApplication needs to load Subapplication (SubApplication can not inject yourself and start to listen for events generated by MainApplication
    - there are security domains, when you load something from your domain probably you trust it and it is in the same domain otherwise it is in different

    I was trying to follow the information in this document http://livedocs.adobe.com/flex/3/loading_applications.pdf
    especially the section called “communication accross domains” page number 15. But either it is not doable or I am doing something wrong because I was able to send events from main to sub but not in the opposite direction.
    The same issue is described here http://opensource.adobe.com/wiki/display/flexsdk/Marshall+Plan
    and the “funny” thing is that contentHolder field does not exist in SWFLoader.

  5. You sir are a life saver! Thank you very much! Worked like a charm. One thing that messed me up was that I had set loadForCompatibility=”true” as I was trying to get my sub-flash app to work. Following your instructions I was able to execute methods but my events would give me errors about being unable to convert events. Well removing the loadForCompatibility solved that issue.

    Once again, thank you!!


Leave a comment


*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

Trackbacks are disabled.