Custom Events in AS 3.0 (don’t forget to override the clone method)

In AS 3.0 you can now create your own Events that extends the Event class.
[as]package.events
{

public class CustomEvent extends Event
{

public static const CUSTOM_TYPE:String = “customType”;

public var customProp:String;

public function CustomEvent( type:String, cp:String, bubbles:Boolean, cancelable:Boolean )
{
super( type, bubbles, cancelable )

customProp = cp;
}

}

}[/as]
This can then be used like so
[as]dispatchEvent( new CustomEvent( CustomEvent.CUSTOM_TYPE, “myProp”, true ) );[/as]
This works fine until you need to re-dispatch the event, in the case that you event doesn’t bubble as its dispatched from an object that isn’t in a displayList. If you do re-dispatch the event like so…

[as]myDispatcher.addEventListener( CustomEvent.CUSTOM_TYPE, onCustomEvent );

private function onCustomEvent( event:CustomEvent ):void
{
dispatchEvent( event );
}[/as]

the event is cast back to the type Event. To solve this you need to override te clone method inside your custom event class. This will keep you event as its original type.
[as]package.events
{

public class CustomEvent extends Event
{

public static const CUSTOM_TYPE:String = “customType”;

public var customProp:String;

public function CustomEvent( type:String, cp:String, bubbles:Boolean, cancelable:Boolean )
{
super( type, bubbles, cancelable )

customProp = cp;
}

public override function clone():Event
{
return new CustomEvent( type, customProp, bubbles, cancelable );
}

}

}[/as]

44 Responses to “Custom Events in AS 3.0 (don’t forget to override the clone method)”

  1. Bjorn Schultheiss says:

    I briefly saw this in the Extending Components doc and wondered why it was required.
    Thanks for explaining it :)

  2. Jon B says:

    Hey, I would like to see some practical real-wrold type uses for creating custom events. Because more often than not the only times I can see to use them they aren’t really required and I’m just interested in what is the best practice really.

  3. p says:

    hey Tink, don’t mean to be the annoying kid front of class but:

    public function CustomEvent( type:String, cp:String, bubbles:Boolean, cancelable:Boolean )….

    …dispatchEvent( new CustomEvent( CustomEvent.CUSTOM_TYPE, true ) );…

    shouldn’t it be: dispatchEvent( new CustomEvent( CustomEvent.CUSTOM_TYPE, “myProp”, true ) );

    ?

    feel free to delete this from comments if I’m correct else slap me down if I’m wrong ;)

  4. Tink says:

    pesky kids ;)

    thanks for pointing it out Paddy, i’ve amended the post.

  5. [...] ter. Totally killed my Flickr API jams. Then, I figured out some nifty ideas, courtesy of this dude, most notably extending Event. Sweet. So, her [...]

  6. sascha/hdrs says:

    Anyone happen to know why I get a Type Coercion failed: cannot convert flash.events::Event@3395a61 to io.file.FileIOEvent when dispatching my custom FileIOEvent from the same class where it’s listener is added with addEventListener?

    If I add the eventListener in the class that should receive the even it works fine:

    addEventListener(FileIOEvent.OPEN, onOpen);

    But if I add the event through the class that is dispatching the event I get the above error. I wrote a method in the event dispatching class to easily add events so that you don’t always have to add all the listeners one by one in every class …

    public function addEventListenersFor(listener:IFileIOEventListener):void
    {
    addEventListener(FileIOEvent.OPEN, listener.onOpen);
    addEventListener(FileIOEvent.PROGRESS, listener.onProgress);
    addEventListener(FileIOEvent.COMPLETE, listener.onComplete);
    addEventListener(FileIOEvent.ABORT, listener.onAbort);
    addEventListener(FileIOEvent.HTTP_STATUS, listener.onHTTPStatus);
    addEventListener(FileIOEvent.IO_ERROR, listener.onIOError);
    addEventListener(FileIOEvent.SECURITY_ERROR, listener.onSecurityError);
    }

    Maybe somebody knows why this happens?

  7. Tink says:

    @sascha

    Can you make an example file and stick the source up somewhere so I can take a look.

  8. sascha/hdrs says:

    Thanks for trying to help Tink! I’ve wrote a very simplified version of my classes but then it turned out that they worked. So now I’m digging in the depth of my concrete classes to find the source of the problem. It’s a bit more complex since there are several inheritances.

  9. sascha/hdrs says:

    Holy lord I fixed it but if you don’t know it you wouldn’t believe what the culprit was! Here it is: I defined constants in my custom Event (FileIOEvent), among them these …

    public static const COMPLETE:String = “complete”;
    public static const ALL_COMPLETE:String = “allComplete”;

    Now guess what happened if I change “allComplete” to something without the word Complete in it? E.g. “allKomplete” … yes that was what caused me three hours of debugging! It seems “complete” and “allComplete” is the same for ActionScripts Event handling, at least in this case. Now please don’t tell me you knew this issue!

  10. Tink says:

    Basically Flex/Flash is firing it’s own “complete” event, and because the event you listen to is defined by a String you are picking them up, but them trying to cast the to your custom event, which is not the type of event that was dispatched.

  11. sascha/hdrs says:

    I’m not sure if you are talking about the same issue. I know AS defines it’s own event COMPLETE with a String “complete” but I don’t think there’s any event with the String “allComplete” in it.

  12. Tink says:

    If there aint one defined as “allComplete” you shouldn’t get the problem with it, the prob is that there is one ;)

    http://bugs.adobe.com/jira/browse/FB-13345?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

  13. sascha/hdrs says:

    gah! should have known that earlier!

  14. [...] Morearty :: Common E4X pitfalls Events Oliver Merk :: Flex Custom Events – Part 1 Tink :: Custom Events in AS 3.0 (don’t forget to override the clon [...]

  15. [...] Morearty :: Common E4X pitfalls Events Oliver Merk :: Flex Custom Events – Part 1 Tink :: Custom Events in AS 3.0 (don’t forget to override the clon [...]

  16. [...] :: Common E4X pitfalls Events Oliver Merk :: Flex Custom Events – Part 1 Tink :: Custom Events in AS 3.0 (don’t forget to override the clo [...]

  17. [...] Morearty :: Common E4X pitfalls Events Oliver Merk :: Flex Custom Events – Part 1 Tink :: Custom Events in AS 3.0 (don’t forget to override the clon [...]

  18. Marcel Fahle says:

    Sascha and Tink,

    nice one.. Just had the same problem. I named an event ACTIVATE (activate) and I got the “cannot convert” error msg. changed it to something else, et voilá, worked.
    Thanks guys!

  19. [...] ages/image-004.jpg"/> </slides> Custom Events There are a few tutorials out there if you are interested in understanding a bit more [...]

  20. Cardin says:

    Thank you for your post. The thing about the Event.clone() method is completely out of the blue, I got an error message that fortunately was solved by overriding clone().

    How I got this error: I created a custom class FlyEvent that inherited Event. Then using the standard EventDispatcher, i dispatchEvent() the custom event twice. The first time it got routed by a parent .addEventListener, which captured it as FlyEvent, and dispatched it again by casting it to Event again.

    This double-casting caused the following error. I think it will be helpful to others in identifying the cause behind the error. =)

    TypeError: Error #1034: Type Coercion failed: cannot convert flash.events::Event@10edb521 to src.Creature.Events.FlyEvent.
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at src.Creature::FlyManager$/broadcastEvent()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at src.Creature::Fly/deathSequence()
    at src.Creature::Fly/movement()
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()
    TypeError: Error #1034: Type Coercion failed: cannot convert flash.events::Event@10edb521 to src.Creature.Events.FlyEvent.
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at src.Creature::FlyManager$/broadcastEvent()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at src.Creature::Fly/deathSequence()
    at src.Creature::Fly/movement()
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()

  21. [...] to share a quick gotcha. It’s really not a gotcha, and really more something I forgot to do. Click here to see the post that helped jog my memory on this one. Hope this will come in handy for [...]

  22. Rick says:

    Hmm.. I wrote a really simple example of dispatching custom events in as3. You can see it at my blog here: http://www.as3blog.org/?p=75

  23. Moata says:

    thank you toooooooooooooooooooooooooooooooooo much…you help me tooooo much thanks :) ……hahahaahahah…thanks

Leave a Reply