20
Nov
07

Dispatching Custom Events

In Chapter 3, we cover the basics of using events. One topic that's not covered extensively (appearing in later chapters), is using the dispatchEvent() method to send a specific, or even custom, event. This method is contained within the EventDispatcher class.

The dispatchEvent() method takes an Event object as its first and only argument. The following code will dispatch a custom event of type "my event":

dispatchEvent(new Event("my event"));

You can also use any AS3 event constant:

dispatchEvent(new Event(Event.INIT));

The below class dispatches an event after a one second timer has elapsed:

package {

    import flash.events.EventDispatcher;
    import flash.utils.Timer;
    import flash.events.*;

    public class DispatchEventExample extends EventDispatcher {

        private var _timer:Timer;

        public function DispatchEventExample() {
            _timer = new Timer(1000, 1);
            _timer.addEventListener(TimerEvent.TIMER, onTimer,
                                    false, 0, true);
            _timer.start();
        }

        private function onTimer(evt:TimerEvent):void {
            dispatchEvent(new Event("one second elapsed"));
        }
    }
}

To listen for the event, use the addEventListener() method. Similar to when dispatching events, as discussed previously, you can either listen for an event constant (such as Event.ENTER_FRAME, or your own custom event class), or a simple string. Here is an example document class that listens for the "one second elapsed" event:

package {

    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite {

        private var _dispatchExample:DispatchEventExample;

        public function Main() {
            _dispatchExample = new DispatchEventExample();
            _dispatchExample.addEventListener("one second elapsed",
                                      onOneSecond, false, 0, true);
        }

        private function onOneSecond(evt:Event):void {
            trace("_dispatchExample has dispatched an event");
        }
    }
}


 

A Note About EventDispatcher and DisplayObjectContainer

It's important to note that display object containers subclass the EventDispatcher class:

Object -> EventDispatcher -> DisplayObject -> InteractiveObject -> DisplayObjectContainer

This means that any sprite, movie clip etc., has the ability to use dispatchEvent().

 

Applied Example

We've added a class to our set of packages called OpenSlider. It's a robust, easily skinnable slider class. See it in action below:

This movie requires Flash Player 9. Please update your player.

Download: OpenSlider  Download OpenSlider (35.1 KB, 143 hits)

The OpenSlider class only needs the instance names of two display objects on the stage. The rest is done behind the scenes:

var scribbleSlider:OpenSlider = new OpenSlider(scribbleBtn,
                                               scribbleLine);

OpenSlider dispatches a CHANGE event when the slider is dragged to a new position. To listen for this event you would write something along the lines of:

scribbleSlider.addEventListener(Event.CHANGE, onSliderChange,
                                false, 0, true);

Once the event is received you can access the percent getter for the slider to read it's new value:

function onSliderChange(evt:Event):void {
    trace(evt.target.percent);
}

Alternatively, if you want values in a range other than 0-1 you can use the setRange() method and then get or set value property:

// set range
scribbleSlider.setRange(-5, 5);

// read value
trace(scribbleSlider.value);

What's important about OpenSlider in the context of this post is that it uses dispatchEvent() internally. Without getting too deeply into the class as a whole, here is a bit of code that shows where the dispatchEvent() method is used:

private function onBtnDown(evt:MouseEvent):void {
	_btn.stage.addEventListener(MouseEvent.MOUSE_UP,onBtnUpOutside);
	_btn.startDrag(false,_rect);
	_btn.addEventListener(Event.ENTER_FRAME,onChange);
	_btn.stage.addEventListener(Event.MOUSE_LEAVE,onBtnUp);
}
private function onBtnUp(evt:MouseEvent):void {
	_btn.stopDrag();

	_btn.removeEventListener(Event.ENTER_FRAME,onChange);
	_btn.stage.removeEventListener(Event.MOUSE_LEAVE,onBtnUp);
	_btn.stage.removeEventListener(MouseEvent.MOUSE_UP,onBtnUpOutside);
}
private function onBtnUpOutside(evt:MouseEvent):void {
	if (evt.target!=this) {
		_btn.stopDrag();
		_btn.removeEventListener(Event.ENTER_FRAME,onChange);
	}
	_btn.stage.removeEventListener(Event.MOUSE_LEAVE,onBtnUp);
	_btn.stage.removeEventListener(MouseEvent.MOUSE_UP,onBtnUpOutside);
}
private function onChange(evt:Event):void {
	if (_scrollMode == "horizontal") {
		_percent = (int(_btn.x)-int(_rect.left))/int(_rect.width);
	} else {
		_percent = (int(_rect.bottom)-int(_btn.y))/int(_rect.height);
	}
	dispatchEvent(new Event(Event.CHANGE));
}

To summarize the above, while the _btn display object is being dragged, an ENTER_FRAME is run that recalculates the _percent variable and continuously dispatches a CHANGE event. The ENTER_FRAME event is removed when the _btn display object stops being dragged. To see the rest of the source code for the class, download the demo, above.

The new event model is one of the biggest differences between AS3 and previous versions of ActionScript. Check the related post about dispatching built-in events in specific circumstances, and check back for more posts on this topic.

Share This:
  • Digg
  • del.icio.us
  • Netvouz
  • DZone
  • ThisNext
  • MisterWong
  • Wists
  • blogmarks
  • BlogMemes
  • Fark
  • feedmelinks
  • Furl
  • Ma.gnolia
  • Netscape
  • Reddit
  • Slashdot
  • SphereIt
  • Spurl
  • StumbleUpon
  • Technorati
  • YahooMyWeb
  • BlinkList
  • DotNetKicks
  • LinkaGoGo
  • NewsVine
  • blinkbits
  • co.mments
  • MyShare
Print This Post Print This Post

Related Content



0 Responses to “Dispatching Custom Events”


  1. No Comments

Leave a Reply