September 02, 2006

when is a flex event listener not an event listener?

as i mentioned in my last post, i'm porting a js UI lib over to flex/flash. one of the things this library does is provide several tools for working with images (well map images actually), it does stuff like measure distances, areas, and angles, rubberband zoom boxes (oh how i wish google map et al would wise up and add this functionality natively, click to re-center the map image then do a separate zoom is for the birds), redline maps (mark up the map image with user annotations like "for heaven's sake don't dig here"), etc. the approach we used was to handle each mouse event separately (up, down, move, etc.) and hand off the event processing to whatever the current tool was, essentially a big switch box. well having read up on and researched flex's event processing i thought i'd get "fancy" and add/remove event listeners as a user changed tools. here's the approach i took:
  • create an mxml image object and hang an original set of listeners off it:
    <mx:Image id="theMap" height="400" width="600" source="" toolTip="the map" useHandCursor="false" mouseMove="utils.showCoords(event); utils.doZoomBox(event);" mouseDown="utils.doZoom(event);"/>
  • remove the current listeners and add the new ones as the user changed tools:

this worked perfectly the first time, then the application would fallback to the original set of listeners defined in the mxml image object (i didn't actually see this at first, i just noticed it fellback on the wrong set of listeners). that is, if i switched to a tool to pan the map image, it would work the first time i panned the image, then it would go back to the zoom tool for the next mouse event. couldn't figure this out after a couple of days, went to the flex-coders list, no joy. another day or so of slowly banging my head against the monitor and i finally had to bother matt the-answering-machine chotin. i guess it took matt about 2 minutes to see my self-inflicted problem.

the problem was that the listener i was removing wasn't the same "listener" as i had originally hung off the mxml image object. when you add a "listener" like that in mxml, it isn't actually a listener, rather it's simply code that will get executed. so when i went to remove it and add a new one, what happened was that only the new listener was added, giving each mouse event two "listeners", the original one in the mxml object and the new one added via actionscript. who knew?

the proper way to handle this is to not define "listeners" on your mxml objects but rather add them during initialization. though in fact matt advised that the original js design was the more "traditional" approach, so that's the method i ended up implementing.

i guess this is another example of the kind of support adobe provides. even though matt is now further up the product food chain he still takes the time to answer technical questions. the same can be said for damon, tom and mike on the ColdFusion team (well when mike was still with adobe anwyay). while i suppose there are other communities with this level of company support, bet you can count them on one hand ;-)


Post a Comment

<< Home