In many respects, I haven't been overly impressed with the F04 (Flash MX 2004) update, though I'm reserving my final opinion for a month or so, until I've really dug deeply into it. Tonight though, chatting with Phil Chung, I ran into something I'm really impressed by: eventDispatcher

I thought I'd should provide a run-down of it here, as it appears well thought out, and very flexible (though I'll probably write an extension to it to fulfill my short wishlist of missing features). Whoever thought this one up at Macromedia should be proud.

Read on...

There are two aspects to using eventDispatcher: dispatching (broadcast) events from an object, and subscribing to those events.

Using EventDispatcher in your own classes to dispatch events is simple: use the mx.events.EventDispatcher class's initialize() method in the class constructor to set up your instances as dispatchers, then simply call dispatchEvent to send out an event.

For example, the following class will dispatch an event every time its sendMessage() method is called.

// in MessageBroadcaster.as
class MessageBroadcaster {
 	// we have to declare the dispatchEvent,
 	// addEventListener and removeEventListener
 	// methods that EventDispatcher sets up:
 	function dispatchEvent() {};
 	function addEventListener() {};
 	function removeEventListener() {};
 	
 	function MessageBroadcaster() {
  		// set instances up as dispatchers:
  		mx.events.EventDispatcher.initialize(this);
  	}
 	function sendMessage(p_msgtxt:String):Void {
  		// set up the event object:
  		var eventObj:Object={target:this,type:"message"}
  		eventObj.msgtxt = p_msgtxt;
  		// dispatch the event
  		dispatchEvent(eventObj);
  	}
}

Notice the construction of the object that it passes as it's parameter. This "event object" must include a target variable with a reference to the object that dispatched the event, and a type variable that indicates the type of event (ex. "click", "change", "update"). You can also include other variables containing data specific to the event (such as the msgtext variable in the example). This is a very flexible model in itself.

Now the most impressive part comes in when you look at the options to subscribe objects to events. Macromedia has provided three ways of doing so, and they're all very useful:

The first method acts almost exactly like addListener() in AS1.0 - you subscribe an object to listen to an event, and the method corresponding to the type of that event will be triggered when they occur. For example:

// in the FLA:
// instantiate a MessageBroadcaster:
myMB = new MessageBroadcaster();

// define an object to listen to myMB:
myObj = {};
myObj.message = function(p_eventObj) {
 	trace("myObj received a message: "+p_eventObj.msgtxt);
}
// subscribe myObj to myMB:
myMB.addEventListener("message",myObj);

// trigger the event:
myMB.sendMessage("I love everyone!");

The second approach is a nice twist on the above. Instead of having to define a function for each event you choose to subscribe to, you can define one function called "handleEvent" that will receive every event, and can sort them out based on the type and target data passed with the event object. This means you don't have to create a set of otherwise useless objects to handle events. For example, in the following example, the message() function of myObj will not be triggered, because the handleEvent function is present.

// in a FLA:
// instantiate a MessageBroadcaster:
myMB = new MessageBroadcaster();

// define an object to listen to myMB:
myObj = {};
myObj.message = function(p_eventObj) {
 	trace("myObj received a message: "+p_eventObj.msgtxt);
}
myObj.handleEvent = function(p_eventObj) {
 	trace(p_eventObj.type+" from: "+p_eventObj.target);
}
// subscribe myObj to myMB:
myMB.addEventListener("message",myObj);

// trigger the event:
myMB.sendMessage("I love everyone!");

Very nice! But we have a third option, which I think is a stroke of genius. Instead of subscribing an object to receive events, you can subscribe a function or a method. This means that you can do brilliant things like assigning different methods in a class to deal with specific events from different objects. Let's look at an example:

// in a FLA:
// instantiate a couple of MessageBroadcasters:
myMB1 = new MessageBroadcaster();
myMB2 = new MessageBroadcaster();

// define an object to listen to myMB:
myObj = {};
myObj.message1 = function(p_eventObj) {
 	trace("Message from myMB1: "+p_eventObj.msgtxt);
}
myObj.message2 = function(p_eventObj) {
 	trace("Message from myMB2: "+p_eventObj.msgtxt);
}
// subscribe myObj to both MessageBroadcasters:
myMB1.addEventListener("message",myObj.message1);
myMB2.addEventListener("message",myObj.message2);

// trigger the events:
myMB1.sendMessage("I love everyone!");
myMB2.sendMessage("I hate everyone!");

Lovely! That almost made my day. For more information on this topic, please visit Phil's blog.