View Full Version : question about custom events dispatching
dub_beat
05-01-2008, 10:08 AM
Hi,
Just a quick question to put my mind at rest about custom event dispatching in flash.
say i have a class and i import flash.events.eventdispatcher.
then at some stage in my class I say
this.dispatchEvent(MyEvent)
I get a "call to possibly undefined method" error.
Now if in my class I say
someObj.dispatchEvent the error goes away and the event dispatches fine.
Could somebody please explain this to me?
acolyte
05-01-2008, 10:29 AM
Hi Dub_Beat;
maybe >this is refering to a movieCLip or Sprite not to the ClassObject
are you extending MovieClip or Sprite in the Class where you trie to dispatch the Event ??
dub_beat
05-01-2008, 10:34 AM
Hi acolyte
no I'm not extending sprite or movieclip in the class I'm dispatching from.
Its not a huge problem or anything, I just want to understand why objects can dispatch events while a class (which I guess is an object) can not
thanks
dub
creynders
05-01-2008, 10:35 AM
Hi,
Just a quick question to put my mind at rest about custom event dispatching in flash.
say i have a class and i import flash.events.eventdispatcher.
then at some stage in my class I say
this.dispatchEvent(MyEvent)
I get a "call to possibly undefined method" error.
Now if in my class I say
someObj.dispatchEvent the error goes away and the event dispatches fine.
Could somebody please explain this to me?
If your custom class doesn't extend EventDispatcher (or another class that in turn extends EventDispatcher) then you can't use the methods of the EventDispatcher class.
MovieClip and Sprite both inherit from EventDispatcher, so they can dispatch events.
dub_beat
05-01-2008, 10:38 AM
thankyou :)
The object I used to attach the dispatch event to was a timer object. I guess that must inherit from the event dispatcher too .......
acolyte
05-01-2008, 10:53 AM
package menu.events {
import flash.events.Event;
public class MenuItemEvent extends Event {
public static const MENU_ITEM_CLICK:String = "menuItemClick";
public function MenuItemEvent(type:String,
bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
}
}
package menu {
import flash.display.Sprite;
import flash.events.Event;
import menu.events.MenuEvent;
import menu.events.MenuItemEvent;
public class Menu extends Sprite{
private var _items:Array;
public function Menu() {
this._items = new Array();
}
public function addItem(item:MenuItem):void {
this._items.push(item);
MenuItem(
this.items[this._items.length-1]).
addEventListener(
MenuItemEvent.MENU_ITEM_CLICK,
eventListener);
this.addChild(MenuItem(
this.items[this._items.length-1]));
}
private function eventListener(event:Event):void {
if (event.type == MenuItemEvent.MENU_ITEM_CLICK) {
trace("#2");
this.dispatchEvent(new MenuEvent(
MenuEvent.MENU_CLICK));
}
}
public function get items():Array {
return this._items;
}
public function getItemAt(index:uint):MenuItem {
return MenuItem(this._items[index]);
}
public function length():uint {
return this._items.length;
}
public function removeItemAt(index:uint):void {
this._items.splice(index, 1);
}
public function set items(items:Array):void {
this._items = items;
}
}
}
package menu {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import menu.events.MenuItemEvent;
public class MenuItem extends Sprite {
private var _textField:TextField;
public function MenuItem() {
super();
this.initialize();
}
protected function draw():void {
this.graphics.lineStyle(1, 0, 1);
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(0, 0, 100, 20);
this.graphics.endFill();
}
protected function initialize():void {
this.draw();
this._textField = new TextField();
this._textField.addEventListener(MouseEvent.CLICK, eventListener);
this.addChild(this._textField);
}
protected function eventListener(event:Event):void {
if (event.type == MouseEvent.CLICK) {
if (event.target == this._textField) {
trace("#1");
this.dispatchEvent(new MenuItemEvent(MenuItemEvent.MENU_ITEM_CLICK))
}
}
}
public function get label():String {
return this._textField.text;
}
public function set label(label:String):void {
this._textField.text = label;
}
}
}
package menu.events {
import flash.events.Event;
public class MenuEvent extends Event {
public static const MENU_CLICK:String = "menuClick";
public function MenuEvent(type:String,
bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
}
}
package {
import flash.display.Sprite;
import flash.events.Event;
import menu.Menu;
import menu.MenuItem;
import menu.events.MenuEvent;
public class Application extends Sprite {
public function Application() {
super();
var _menu:Menu = new Menu();
_menu.addEventListener(MenuEvent.MENU_CLICK, eventListener);
var _item:MenuItem = new MenuItem();
_item.label = "Item 5";
_menu.addItem(_item);
this.addChild(_menu);
}
private function eventListener(event:Event):void {
if (event.type == MenuEvent.MENU_CLICK) {
trace("#3");
}
}
}
}
So far as i know : The Time Object does not Inherit but the TimerEvent does
import flash.events.TimerEvent;
creynders
05-01-2008, 11:09 AM
thankyou :)
The object I used to attach the dispatch event to was a timer object. I guess that must inherit from the event dispatcher too .......
Yes. Almost all pre-defined actionscript classes inherit from event dispatcher.
amarghosh
05-01-2008, 11:20 AM
So far as i know : The Time Object does not Inherit but the TimerEvent does
its the other way:
Timer does inherit from EventDispatcher and TimerEvent doesn't (http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Timer.html)
dub_beat
05-01-2008, 11:22 AM
Maybe you could help me understand why this is not working
Custom Event
package rocudo.logger {
import flash.events.*
public class ActionReportEvent extends Event {
public static const FULL:String = "full";
public static const IDLE:String ="idle"
public static const ACTIVE:String ="active"
public var _actions:Array =new Array();
public function ActionReportEvent(type:String, actions:Array,bubbles:Boolean=true, cancelable:Boolean=false) {
_actions=actions
super(type, bubbles,cancelable);
}
public function get data():Array {
return _actions;
}
public override function clone():Event {
return new ActionReportEvent(type, _actions,bubbles,cancelable);
}
}
}
the class that dispatches the event
import flash.events.EventDispatcher;
public class Action extends EventDispatcher{
//---------------action types------------------//
private static const _unknown=0;
private static const _launch=1;
private static const _play=2;
private static const _stop=3;
private static const _idle=4;
private static const _exit=5;
//------------array vars-------------------//
private var _actionArray:Array=new Array();
private var _actionRecord:String;
private var arrayCount:int=0;
public function Action() {
}
/* format data function
formats event data as a string and pushes it into an array
*/
public function formatData(e,id,song,ct):void {
_actionRecord=("actionType:"+e+","+"sessionID:"+id+","+"songID:"+song+","+"contentType"+ct+"|");
_actionArray.push(_actionRecord);
arrayCount++;
canSendData();
}
/*log action function
recieves event info from logger class
and sends it to be formatted as a string.
more logic within here to be added soon.
*/
public function logAction(e,seid,soid,ct) {
var actionType=e.type;
formatData(e.type,seid,soid,ct);
}
/* canSendData funtion
this function is called each time an item is added to the action array.
if the number of items is 30 then send the data & clear the array.
else no nothing.
*/
public function canSendData() {
trace(_actionArray.length);
trace(arrayCount);
if (arrayCount==30) {
this.dispatchEvent(new ActionReportEvent(ActionReportEvent.FULL,_actionAr ray));
_actionArray=[]
arrayCount=0;
//clear action array and send to server;
}
}
/* getArray Count Function
this function is called by the custom timer class.
it returns the current array count.
This value is used by the timer to determine if an idle event should be
broadcast.
*/
public function getArrayCount():int{
var count=arrayCount;
return count;
}
}
}
The class I want to listen for the event
package rocudo.logger{
import flash.events.*;
import rocudo.logger.ActionReportEvent
import flash.display.Sprite;
public class Reporter extends Sprite {
private var _actionArray:Array=new Array();
public function Reporter() {
this.addEventListener(ActionReportEvent.FULL, recieveActionsArray,true,0,false);
}
/* recieveActionsArray function
recieves an array of actions from the actions class
it then sends it to the parseArray function;
*/
public function recieveActionsArray(e:ActionReportEvent):void{
trace("recieved Full event")
// _actionArray=a;
parseActionsArray();
}
/* parseActionsArray function
recieves an array of actions from the actions class
it then sends it to the parseArray function;
*/
private function parseActionsArray():void{
}
}
}
The trace statement in the last block of code does not print out. I'm wondering why that class cant hear the event that was dispatched?
amarghosh
05-01-2008, 11:32 AM
Action class is dispatching the event. it can be listened only by an instance of action class. ie, u have to add listener to an instance of Action class itself.
try this:
public class Reporter extends Sprite
{
private var action:Action;
public function Reporter()
{
action = new Action();
this.action.addEventListener(ActionReportEvent.FUL L, recieveActionsArray);
}
public function recieveActionsArray(e:ActionReportEvent):viod
{}
}
amarghosh
05-01-2008, 11:36 AM
make sure u call logAction with the action instance in the Reporter class itself;
ie this.action.logAction from any method in Reporter class
dub_beat
05-01-2008, 11:53 AM
Hmm I tried that and it didnt work.
package rocudo.logger{
import flash.events.*;
import flash.display.Sprite;
public class Reporter extends Sprite {
private var _actionArray:Array=new Array();
private var action:Action
public function Reporter() {
action= new Action(); ;
action.addEventListener(ActionReportEvent.FULL, recieveActionsArray);
}
/* recieveActionsArray function
recieves an array of actions from the actions class
it then sends it to the parseArray function;
*/
public function recieveActionsArray(e:ActionReportEvent):void{
trace("works from reporter")
// _actionArray=a;
parseActionsArray();
}
/* parseActionsArray function
recieves an array of actions from the actions class
it then sends it to the parseArray function;
*/
private function parseActionsArray():void{
}
}
}
I did however get it to work but not the way I wanted.
public function Action() {
this.addEventListener(ActionReportEvent.FULL, recieveActionsArray);
}
public function recieveActionsArray(e:ActionReportEvent):void{
trace("works")
//parseActionsArray();
}
I really wanted the reporter class to just recieve the array as part of the event. It seems kind of pointless having the same class dispatch an event to its self :(
amarghosh
05-01-2008, 11:57 AM
which class do u call logAction() from? can u post that code?
acolyte
05-01-2008, 12:00 PM
its the other way:
Timer does inherit from EventDispatcher and TimerEvent doesn't (http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Timer.html)
wow yeah thats true - good morning :P everyone
creynders
05-01-2008, 12:04 PM
Hmm I tried that and it didnt work.
I really wanted the reporter class to just recieve the array as part of the event. It seems kind of pointless having the same class dispatch an event to its self :(
That's funny there are many people that seem to think that's what is happening. But it's not. A class dispatches events and registers listeners. It's the listeners that receive the event not the dispatcher.
So, it's not the same class that dispatches an event to its self.
dub_beat
05-01-2008, 12:05 PM
It gets called from a class named logger.
I was trying to make all the o o but I think its gotten a little over my head.
I attached my class files in a zip if you fancy checking them out.
Basically I have my Main class.
In that that I make an instance of Logger.
Logger holds an instance of everything else.
amarghosh
05-01-2008, 12:18 PM
add these to Logger class:
public function Logger(o)
{
_reporter=new Reporter();
_action=new Action();
_action.addEventListener(ActionReportEvent.FULL, handler);
}
private function handler(event:ActionReportEvent):void
{
_reporter.recieveActionsArray(event);
}
or
public function Logger(o)
{
_reporter=new Reporter();
_action=new Action();
_action.addEventListener(ActionReportEvent.FULL, _reporter.recieveActionsArray);
}
now u are adding listener to the same Action instance that is dispatching the event.
EDIT: forget about the action instance i suggested to Reporter class; that's needed when u are calling logAction from Reporter class itself.
dub_beat
05-01-2008, 12:52 PM
Thankyou very much amarghosh!!!
Thanks everyone else aswell for helping me hammer it out
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.