Passing Arguments to Event Listening Methods

I’ve seen this question asked in several forums. Enough, anyway, that I would remark on it. The question takes many a form, but it boils down to this: How does one pass arguments to a method acting as an event listener in Actionscript 3?

In general there are three broad routes to take:

Using a custom object and accessing its properties with the currentTarget property of whatever Event the method is listening for.

Dispatching a custom event which can contain its own properties.

Using a Dictionary object instance to hold references associated with event dispatching objects.

Let’s take a little look at each of these.

With the custom object approach, arguments you wish to access in an event listener are added to the event dispatching object as properties. This is most useful when you want the event handling to be performed in a class which contains the dispatching object.

A quick example:

The custom object:

ActionScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

package{

importflash.display.Sprite;

publicclassCustomObjectextendsSprite{

privatevar_foo:Boolean;

privatevar_bar:int;

publicfunctionCustomObject(foo:Boolean,bar:int):void{

_foo=foo;

_bar=bar;

graphics.beginFill(0x000077);

graphics.drawRect(0,0,100,50);

graphics.endFill();

}

publicfunctiongetbar():int{return_bar;}

publicfunctionsetbar(value:int):void{

_bar=value;

}

publicfunctiongetfoo():Boolean{return_foo;}

publicfunctionsetfoo(value:Boolean):void{

_foo=value;

}

}

}

And document class:

ActionScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

package{

importflash.display.Sprite;

importflash.events.MouseEvent;

publicclassCustomObjectTestextendsSprite{

publicfunctionCustomObjectTest():void{

varco:CustomObject=newCustomObject(true,23);

co.addEventListener(MouseEvent.CLICK,onClick);

addChild(co);

}

privatefunctiononClick(me:MouseEvent):void{

trace(me.currentTarget.foo,me.currentTarget.bar);

}

}

}

As you can see, the foo and bar properties are “passed” to the event listening method as actual properties of the object clicked.

The custom event approach is most useful when you wish event handling to be done within the dispatching object. Here the “passed” arguments are contained inside properties of the dispatched event.

Example:

Custom event class:

ActionScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

package{

importflash.events.Event;

publicclassCustomEventextendsEvent{

publicstaticconstCUSTOM:String="customEvent";

privatevar_foo:Boolean;

privatevar_bar:int;

publicfunctionCustomEvent(type:String,foo:Boolean,bar:int):void{

super(type);

_foo=foo;

_bar=bar;

}

publicfunctiongetfoo():Boolean{return_foo;}

publicfunctiongetbar():int{return_bar;}

}

}

A custom object which dispatches the event:

ActionScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package{

importflash.display.Sprite;

importflash.events.MouseEvent;

publicclassCustomEventObjectextendsSprite{

publicfunctionCustomEventObject():void{

graphics.beginFill(0x000077);

graphics.drawRect(0,0,100,50);

graphics.endFill();

addEventListener(MouseEvent.CLICK,sendCustomEvent);

}

privatefunctionsendCustomEvent(me:MouseEvent):void{

dispatchEvent(newCustomEvent(CustomEvent.CUSTOM,true,23));

}

}

}

And finally a document class which ties it all together:

ActionScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

package{

importflash.display.Sprite;

publicclassCustomEventTestextendsSprite{

publicfunctionCustomEventTest():void{

varceo:CustomEventObject=newCustomEventObject();

ceo.addEventListener(CustomEvent.CUSTOM,onCustomEvent);

addChild(ceo);

}

privatefunctiononCustomEvent(ce:CustomEvent):void{

trace(ce.foo,ce.bar);

}

}

}

Here you can see the “arguments” are accessed in the event listener as properties of the dispatched event.

Finally, the Dictionary approach is probably the least object oriented of the bunch but sometimes it’s just what the doctor ordered. Here the arguments we wish to pass to the event listener are stored in a dictionary and associated with the event dispatching object. Using this approach it’s easy to maintain everything in a single class such as this:

ActionScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

package{

importflash.display.Sprite;

importflash.events.MouseEvent;

importflash.utils.Dictionary;

publicclassDictionaryTestextendsSprite{

privatevar_dict:Dictionary

publicfunctionDictionaryTest():void{

_dict=newDictionary();

varclickableSprite:Sprite=newSprite();

clickableSprite.graphics.beginFill(0x000077);

clickableSprite.graphics.drawRect(0,0,100,50);

clickableSprite.graphics.endFill();

clickableSprite.addEventListener(MouseEvent.CLICK,onClick);

_dict[clickableSprite]=[true,23];

addChild(clickableSprite);

}

privatefunctiononClick(me:MouseEvent):void{

trace(_dict[me.currentTarget][0],_dict[me.currentTarget][1]);

}

}

}

Of course there are other more or less complicated methods of getting the job done, but they follow the same general guidelines (such as adding properties willy nilly to dynamic classes like MovieClips, which is basically the same as using a custom object but not generally recommended, or using objects as associative arrays rather than a Dictionary instance).