About Orland MediaDevelopmentTrainingBlogRSS FeedContact us
Microphone

Passing parameters to a MouseEvent listener

Date: Tuesday 19th January 2010
Time: 14:27
Category: ActionScript 3.0
Views: 176
Comments: 2 Comments

Mouse Event

Problem:

Here is how we construct a MouseEvent handler in ActionScript 3.0:

myButton.addEventListener(MouseEvent.CLICK, openURL, false, 0, true);

private function openURL(e:MouseEvent):void
{
   navigateToURL(new URLRequest("http://www.mysite.com"), "_blank");
}

Note that we set the fourth parameter, useWeakReference, to true. This ensures that if this listener is the the only reference to the myButton remaining, myButton can still be garbage collected if required.

The trouble with this is that every time myButton is clicked, the same URL will open. We can’t easily pass a parameter to the function which is acting as a listener. How can the same function be used by many buttons to open a different URL for each button? How can we pass a parameter?

Solution 1: Custom events (won’t work):

It would be nice if we could dispatch a custom event on mouse click. Custom events extend the event class enabling us to dispatch an event with additional properties (like a URL). This event is received by the handler then the property is accessed. The trouble is this approach won’t work here because the Flash Player automatically dispatches MouseEvents, we don’t dispatch them ourselves. (If anyone sees a way this may be done, please comment below.)

Solution 2: Embed the function call (not advised):

An interesting strategy is used here, whereby a call to a function is used as the event handler, and this returns the function to use, including the desired parameter. The trouble with this approach is that it is not really good form, in that there is no way we can reference the handler if we did want to remove it using removeEventListener().

We’re beginning to see that there is actually no way to “pass” a parameter, really. We have to rather detect the button-specific value by “association”. The following solutions all achieve this by using the MouseEvent’s target property:

Solution 3: Use a switch statement on the event’s target property

When the button is clicked, providing there is no further mouse-enabled object inside it, that button is the event’s target. We can say it dispatched the event. We can access the target object that dispatched the event using a property of the event itself:

myButton.addEventListener(MouseEvent.CLICK, openURL, false, 0, true);

private function openURL(e:MouseEvent):void
{
   trace(e.target + "dispatched this event!");
   navigateToURL(new URLRequest("http://www.mysite.com"), "_blank");
 }

If we can access the target we can decide what to do in the handler depending on the target:

myButton.addEventListener(MouseEvent.CLICK, openURL, false, 0, true);

private function openURL(e:MouseEvent):void
{
   var u:URLRequest = new URLRequest;

   switch(e.target)
   {
      case myButton:
         u.url = "http://www.mysite.com";
         break;

      case myOtherButton:
         u.url = "http://www.myothersite.com";
         break;

      default:
         throw new Error("No URL set for " + e.target);
         return;
   }

   navigateToURL(u, "_blank");
}

This works well.

Solution 4: Use a public custom property inside the dispatching object

We could avoid a switch statement and instead have a property inside the dispatching class which can then be detected. So if our button extends Sprite, let’s say, we could have an instance property in there called url and we could detect that, as follows:

myButton.addEventListener(MouseEvent.CLICK, openURL, false, 0, true);

private function openURL(e:Event):void
{
   var u:URLRequest = new URLRequest;
   navigateToURL(new URLRequest(e.target.url), "_blank");
 }

This is fine too, but we might need to throw an error if the object dispatching the event doesn’t have a url property.

Solution 5: Use a dictionary object to track variables

Dictionary objects in ActionScript are similar to associative arrays but they can accept complex objects, as opposed to strings, as their keys. After creating our button we could push a reference to it into a dictionary and specify a value to associate with it, like this:

var dict:Dictionary = new Dictionary(true);  // use weak references to the objects
var myButton:Sprite = new Sprite;
dict[myButton] = "http://www.mysite.com";
addChild(myButton);

myButton.addEventListener(MouseEvent.CLICK, openURL, false, 0, true);

private function openURL(e:MouseEvent):void
{
   navigateToURL(new URLRequest(dict[e.target]), "_blank");
}

This is perfectly workable too.

Solutions 3, 4 and 5 all seem equally good solutions to this problem. There is just one final option, which is to avoid the problem altogether by using separate listeners for each button. But that, of course, is what we were trying to solve in the first place. :D

Rate this post
1 star2 stars3 stars4 stars5 stars   (1 votes, average: 5.00 out of 5)

Flash course in London

Date: Monday 18th January 2010
Time: 14:20
Category: ActionScript 3.0
Views: 62
Comments: No comments

We are tentatively scheduling our next ActionScript 3.0 training course for 17th -19th February in central London.

As a start to the new year, we’re applying a 25% discount for all trainees – and an additional 25% for those who are self funded!

If you would like to attend the course please get in touch. :)

Rate this post
1 star2 stars3 stars4 stars5 stars   (Roll over and click)

Flash ActionScript 3 course in London

Date: Wednesday 4th November 2009
Time: 13:14
Category: ActionScript 3.0
Views: 148
Comments: No comments

We’ve scheduled our next Applied ActionScript 3 training course for 25th-27th November here in London. The course teaches how to build a real-world application entirely using ActionScript 3.

If you’d like to attend the course please get in touch.

Rate this post
1 star2 stars3 stars4 stars5 stars   (1 votes, average: 5.00 out of 5)

Arthropod Debugger

Date: Tuesday 20th October 2009
Time: 00:05
Category: ActionScript 3.0
Views: 138
Comments: 1 Comment

Problem

You want to be able to see trace statements etc. whether your application is in Test Movie mode, running locally over HTTP or running remotely over HTTP in the browser plug-in. You don’t want to use the the Flash Debugger and you don’t want to have to install Flash Debug players. You just want to see trace() statements – in a more aesthetically pleasing window if possible..

Solution

Rate this post
1 star2 stars3 stars4 stars5 stars   (2 votes, average: 5.00 out of 5)

Why use init methods in AS3

Date: Tuesday 29th September 2009
Time: 23:43
Category: ActionScript 3.0
Views: 391
Comments: No comments

Checking our stats, we just saw that some people are searching for “why use init methods as3″. There are several reasons to consider using init methods in AS3, rather than have all of your initialisation code in your constructor functions:

  • Constructor functions run slower than “regular” methods. (See here for details.)
  • You might want to re-run initialisation code without recreating the instance.
  • You might want to run delayed initialisation code, for example once an object has been added to the Display List. (See our post here regarding this issue.)
Rate this post
1 star2 stars3 stars4 stars5 stars   (1 votes, average: 4.00 out of 5)
Older posts
Lenovo Microsoft Adobe Heart Internet Envirowise
Copyright © 2008 Orland Media Ltd | All rights reserved Company details Ethical policy Terms & conditions Privacy policy