I had a heck of a time finding information about how to use the Flex EventDispatcher class to generate custom events. I eventually found some information about what Macromedia calls mixins. Basically, they are a way of inserting methods into a class from another class without using subclassing. The example shows how to set up the EventDispatcher class as a mixin, but doesn’t actually show how the event handling works. I am providing an example here showing a couple of the EventDispatcher methods in actual use.
Note that it appears that events generated from one custom class do not propagate to another custom class, so if you want the events to propagate to multiple custom classes, it is probably best to set up a central event dispatcher class that is called from any invoking class, and then redirects the event to all other classes that need to handle that particular event. Sort of defeats registering a class as a listener, but it does still make implementation cleaner.
Note that this code is designed to work along side other code, and will not work on its own. It is meant just to illustrate the implementation.
class FolderController
{
// properties
private var pView:Object;
private var pCurrentFolder:String;
private var pViewingCustomFolder:Boolean;
// --------------------------
// Start code to enable custom events (implement mixin)
static function Initialize():Boolean {
var p = FolderController.prototype;
mx.events.EventDispatcher.initialize(p);
return true;
}
// Call the Initialize() method.
static var mixit : Boolean = FolderController.Initialize();
// Declare mixed-in methods.
var dispatchEvent: Function;
var addEventListener: Function;
var removeEventListener: Function;
// End code to enable custom events
// --------------------------
// constructor
public function FolderController()
{
// Register for events
addEventListener("messagesDeleted", onMessagesDeleted);
addEventListener("defaultFolderSelected", handleFolderSelected);
addEventListener("customFolderSelected", handleFolderSelected);
addEventListener("customFolderDeleted", onCustomFolderDeleted);
}
public function handleFolderSelected(event:Object):Void {
if (event.type == "defaultFolderSelected") {
if (event.selectedIndex > -1 && event.selectedIndex != undefined) {
pViewingCustomFolder = false;
pView.customFoldersGrid.selectedIndex = -1;
pView.mailGrid.selectedIndex = -1;
pView.messagesService.send({folderName:event.folderName});
pView.deleteFolderButton.enabled = false;
}
} else if (event.type == "customFolderSelected") {
if (event.selectedIndex > -1 && event.selectedIndex != undefined) {
pViewingCustomFolder = true;
pView.defaultFoldersGrid.selectedIndex = -1;
pView.mailGrid.selectedIndex = -1;
pView.screenController.updateMessageArea();
pView.messagesService.send({folderName:event.folderName});
pView.deleteFolderButton.enabled = true;
}
}
}
public function onMessagesDeleted(event:Object):Void
{
var folderItem = event.activeFolderGrid.getItemAt(event.activeFolderIndex);
folderItem.MESSAGES_COUNT = Number(folderItem.MESSAGES_COUNT) - event.selectedIndices.length;
event.activeFolderGrid.selectedIndex = event.activeFolderGrid.selectedIndex;
}
public function onCustomFolderDeleted(event:Object):Void
{
trace("rowCount:" + event.deletedFolderIndex + ":" + pView.customFoldersGrid.rowCount);
pView.customFoldersGrid.removeItemAt(event.deletedFolderIndex);
if (event.deletedFolderIndex < pView.customFoldersGrid.dataProvider.length) {
pView.customFoldersGrid.selectedIndex = event.deletedFolderIndex;
} else if (pView.customFoldersGrid.dataProvider.length > 0) {
pView.customFoldersGrid.selectedIndex = pView.customFoldersGrid.dataProvider.length - 1;
} else {
pView.customFoldersGrid.selectedIndex = -1;
}
pView.customFoldersGrid.dispatchEvent({type:"change"});
}
public function set folderView(folderHandle:Object):Void
{
pView = folderHandle;
}
}
In Flex, you instantiate the above class just by putting the following shortly after your main <mx:Application> tag:
<FolderController id="myFolderController" />
and at that point you can send an event to your custom class by invoking:
myFolderController.dispatchEvent({type:"messagesDeleted", activeFolderGrid:myFolderGrid, ... });
or dispatch an event within the class itself by:
dispatchEvent({type:"messagesDeleted", activeFolderGrid:myFolderGrid, ... });