<

Go Premium for a chance to win a PS4. Enter to Win

x

Creating a custom event listener in AS3

Published on
12,231 Points
6,031 Views
2 Endorsements
Last Modified:
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
Technology Partners: 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Join & Write a Comment

In this tutorial viewers will learn how to create a basic motion tween animation in Flash Open a new document in Flash: Draw/import an image: Press CTRL + F8 to convert it into a graphic symbol: Select a frame (how long you want the tween to last): …
The goal of the tutorial is to teach the user how to how to load their YouTube profile onto Flash Media Live Encoder.
Suggested Courses
Course of the Month11 days, 13 hours left to enroll

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month