<

Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x

Creating a custom event listener in AS3

Published on
12,283 Points
6,083 Views
2 Endorsements
Last Modified:
Approved
I come across a lot of question about how to access things in the document class from a movieclip, or accessing something from a movieclip in the document class.

It took me a while to figure this out but once I did it makes life so much easier.

By creating a CustomEvent class and placing it in your own utils folder and setting up your AS3 class path, once you import the Custom Event, this is how you'd go about it.

your class would look something like this ...

package whatever.utils //change your package name as required
{
 import flash.events.Event;

    public class CustomEvent extends Event
    {
       
      public static const NOTIFY:String = "notify";
        public var data:*;
            
       public function CustomEvent(type:String, data:*,  bubbles:Boolean = false, cancelable:Boolean = false){
                  super(type, bubbles, cancelable);
            this.data = data;
        }
    }
}

to implement

say you have a nested movieclip that when it hits frame 5 you want to execute a function in the document class called callSomething();

when you add the movieclip in your document class

addChild(nameOfMovieClip);
//add the dispatcher

nameOfMovieClip.addEventListener(CustomEvent.NOTIFY, handleNotifyRoot);

//note the CustomEvent.NOTIFY part - you can add items in your CustomEvent class

Create a handleNotifyRoot method in your document class

function handleNotifyRoot(e:CustomEvent):void
{
trace(e.data.myData.toString());
}

in the movieclip when you want the event to trigger, you must dispatch the event

var varString:String = "clicked ball";
dispatchEvent(new CustomEvent(CustomEvent.NOTIFY, {myData:varString}));



you can pass anything to your custom event.

I hope this all makes sense.
2
Comment
Author:blue-genie
  • 4
  • 3
  • 2
9 Comments
 
LVL 7

Expert Comment

by:AreDubya
blue-genie,

This is awesome! I think (italics needed there) I understand this, and I am excited to use it. You say to "note the CustomEvent.NOTIFY part - you can add items in your CustomEvent class". What is accomplished with the items? I am thinking they would be used to trigger different actions in the CustomEvent function? Also, how is callSomething() executed? Great article.

Thanks,

AreDubya

0
 
LVL 39

Author Comment

by:blue-genie
Hi  AreDubya, glad you found this useful cause this has been the best thing for me.
you can reuse your class for multiple projects so i have for example

CustomEvent.NOTIFY //notifies my document class something has happened
CustomEvent.UPDATE_VARIABLES etc

>>I am thinking they would be used to trigger different actions in the CustomEvent function?

not really (sorry i'm really bad at explaining things)

assume you have a StartButton Class and a PrizeBanner class.
the button might dispatch an event to let the document class know it was pressed

your PrizeBanner class might load some data from php file, once the data is retrieved it might dispatch a method to say update a score variable.

in your document class when you add StartButton

sb = new StartButton();
//other stuff
addChild(sb);
sb.addEventListener(CustomEvent.NOTIFY,doNavigation);


private function doNavigation():void {
//stuff here
}

pb = new PrizeBanner();
addChild(pb);
pb.addEventListener(CustomEvent.NOTIFY,updateScore);

private function updateScore():void
{
//var score
}
0
 
LVL 7

Expert Comment

by:AreDubya
blue-genie,

Thanks! I am trying to learn oop (got a book - no time to read!), so some of this is at the edge of my knowledge. Hopefully some experimentation will bring more understanding. In any event, this is something I had beaten my head against the wall over and basically written off so thanks again for the great article.

AreDubya
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 7

Expert Comment

by:AreDubya
Hey blue-genie,

You are in S. Africa, right? Some friends are performing in Johannesburg and Cape Town through the rest of April, if you are in/near one of those let me know and I will hook up some tickets for you. You can get me at {rickwillett at comcast dot net}.

AreDubya
0
 
LVL 39

Author Comment

by:blue-genie
:-) will mail you.
0
 
LVL 7

Expert Comment

by:AreDubya
blue-genie,

I just noticed they finish in Johannesburg on the 11th, then open in Cape Town on the 14th. So, if Johannesburg is better for you shoot me that email soon!

AreDubya
0
 
LVL 9

Expert Comment

by:Jakob_E
Hi Blue-Genie,

Thumbs up for addressing custom events - too few know about this.
I have a few comments though.

1) I prefer using whatever.events - this is more aligned with the flash namespace structure
2) I like to use get and set functions - this way you can make data read-only
3) In most cases I would make the data value optional (data:*=null)
4) You should always override the clone and toSrting methods

While 1-3 is my personal likings the 4'th isn't.

// clone example:
var event1:CustomEvent=new CustomEvent(CustomEvent.NOTIFY, {name:"foo", value:bar });
var event2:CustomEvent=event1.clone()
trace(event1.data); // returns [object Object]
trace(event2.data); // without the override clone this will cause an error

// toString example:
var event:CustomEvent=new CustomEvent(CustomEvent.NOTIFY, {name:"foo", value:bar });

addEventListener(CustomEvent.NOTIFY,customEventHandler,false,0,true);
dispatchEvent(event)

private function customEventHandler(e:CustomEvent):void{
  trace(e);
  // without: [Event type="notify" bubbles=false cancelable=true eventPhase=2]
  // with:      [CustomEvent type="notify" data=[object Object] bubbles=false cancelable=true eventPhase=2]
}


// CustomEvent class:
package whatever.events {
    import flash.events.Event;

    public class CustomEvent extends Event {
       
        public static const NOTIFY:String = "notify";
        private var _data:*;
           
        public function CustomEvent(type:String, data:*=null, bubbles:Boolean=false, cancelable:Boolean=false){
            super(type, bubbles, cancelable);
            _data = data;
        }
        override public function clone():Event {
            return new CustomEvent(type, data, bubbles, cancelable);
        }
        override public function toString():String {
            return formatToString("CustomEvent", "data", "type", "bubbles", "eventPhase");
        }
        public function get data():*{
            return _data;
        }
       
    }
}


Thanks and keep up the good work :)
Jakob E


0
 
LVL 39

Author Comment

by:blue-genie
Thanks for your feedback Jakob - much appreciated by all of us I'm sure.
When I first started with AS3 I couldn't figure out how to achieve this and eventually arrived at this solution which worked well for me thus far.  I should have mentioned it's how I do it but not necessarily the best way. Usually in the posts I do that but I was repeating myself so many times that I ended up doing this article.


1. explain #1 to me please
2. the get/set option sounds familiar from my Java days. My OOP knowledge and experience is limited.
3. making data null optional would make this much more generic thus better I agree.
4. why?explain.
0
 
LVL 9

Expert Comment

by:Jakob_E

Hi Blue-Genie,

The reason why I like the whatever.events namespace structure
is that it matches the one used by flash - making it easier to remember.

import flash.events.Event
import whatever.events.CustomEvent


About the clone and toString overrides:

Event.clone() is used when re-dispatching an event (dispatchEvent(e)). If you don't add
all the properties then the properties of the re-dispatched event won't have the right values
when listeners handle the re-dispatched event. In our case data will be lost.  

An example:
// Add two listeners:
stage.addEventListener(CustomEvent.NOTIFY,firstDispatchHandler,false,0,true)
button.addEventListener(CustomEvent.NOTIFY,secondDispatchHandler,false,0,true)

// Dispatch the CustomEvent on the first                           
stage.dispatchEvent(new CustomEvent(CustomEvent.NOTIFY,{name:"John Doe"}))

private function firstDispatchHandler(e:CustomEvent):void{
    trace("First: "+e.data.name) // traces "John Doe"
    // Re-dispatch event to the second listener
    dispatchEvent(e)
}

private function secondDispatchHandler(e:CustomEvent):void{
    trace("Second: "e.data.name)
    // Without the clone override you'll get an error:
    // TypeError: Error #1034: Type Coercion failed: cannot convert
    // flash.events::Event@54122a01 to whatever.events.CustomEvent.
}



Event.toString() is not required but I find it useful when unsure about what properties is
passed thru the event.

If you don't override Event.toString() tracing your CustomEvent will show:
[Event type="notify" bubbles=false cancelable=true eventPhase=2]

When overriding you'll get this:  
[CustomEvent type="notify" data=[object Object] bubbles=false cancelable=true eventPhase=2]
Now we know that the event is a CustomEvent with a data property  (in this case an object).
 
Tracing events becomes even more useful when dealing with more "advanced" types - like the MouseEvent:
[MouseEvent type="mouseOver" bubbles=true cancelable=false eventPhase=2 localX=38 localY=41 stageX=265.95
stageY=123 relatedObject=null ctrlKey=false altKey=false shiftKey=false buttonDown=false delta=0]
 

Hope it makes sense :)

Best,
Jakob E
 

 


0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Join & Write a Comment

The goal of the tutorial is to teach the user how to use the auto adjust feature and what the different options do. When your video is not working right you can choose the auto adjust feature to help choose your settings.
This Micro Tutorial will teach to how to utilize bit rate in Adobe Flash Media Live Encoder.
Suggested Courses

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month