Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flex - Problem with ResizeEvent.RESIZE

I'm having a little problem with my resize event... I created a component myself, and this component, at each resize event, runs a complex method. Here is the problem: When I maximize or restore my window, this event is called several times in a real short period of time, not letting enough time to my method to run completely before another one starts... I'd like to know if there is anyway of only run this method in the end of each resize movement. Thanks

like image 678
Andre Mariano Avatar asked Jan 22 '10 18:01

Andre Mariano


4 Answers

Instead of reacting to a ResizeEvent, which will fire every frame during a resize (i.e. if you hit maximize and it takes 3 frames for the component to redraw from widh/ehight = 0 to width/height = MaxValue) then the resize event will fire three times, you could 'watch' the properties of width and height.

var widthWatch:ChangeWatcher = ChangeWatcher.watch(this, 'widht', resizeHandler)
var heightWatch:ChangeWatcher = ChangeWatcher.watch(this, 'height' resizeHandler)

this will, in effect, watch the properties, similar to data binding, and execute your resizeHandler whenever the width or height change. This has a slight drawback as to firing your handler twice if width and height change at the same time, but that can be solved with a third function that does the work, which gets invoked by your handlers if it isn't schedule to be invoked. The code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete(event)">
<mx:Script>
 <![CDATA[
  import mx.binding.utils.ChangeWatcher;

  private var widthWatch:ChangeWatcher;
  private var heightWatch:ChangeWatcher;
  private var resizeExecuting:Boolean = false;

  private function onCreationComplete(event:Event):void
  {
   widthWatch = ChangeWatcher.watch(this,'width',onSizeChange);
   heightWatch = ChangeWatcher.watch(this,'height',onSizeChange);
  }

  private function onSizeChange(event:Event):void
  {
   if(!resizeExecuting)
    callLater(handleResize);
   resizeExecuting = true;
  }

  private function handleResize():void
  {
   //do expensive work here
   resizeExecuting = false;
  }

  private function stopWatching()
  {
   //invoke this to stop watching the properties and prevent the handleResize method from executing
   widthWatch.unwatch();
   heightWatch.unwatch();
  }

 ]]>
</mx:Script>
</mx:Application>

I prefer the change watcher method because it fires after the width and height properties have changed, unlike a resize event wich fires before the width and height properties are correclty updated.

like image 109
David Avatar answered Oct 24 '22 08:10

David


You'll want to coalesce the resize events into a single event. David Coletta talked briefly about event coalescing in this presentation, but I don't remember if he described how he did it.

You could do this in a number of ways, one of which I'll layout in pseudo code below:

resizeHandler(resizeEvent):
   if (resizeEventReceived)
       return
   resizeEventReceived = true
   Timer.startIn(30 /*ms*/).withHandler(doResize)

doResize(timerEvent):
    /* do actual resize processing */
    resizeEventReceived = false
like image 22
Kaleb Pederson Avatar answered Oct 24 '22 09:10

Kaleb Pederson


It sounds to me like you're doing something in your event handler that is causing a new ResizeEvent.RESIZE to be fired. Since ActionScript runs in a single thread, no independent source could possibly dispatch that event while your handler is running unless you somehow trigger it.

like image 1
Josh Tynjala Avatar answered Oct 24 '22 07:10

Josh Tynjala


I would like to point out that flex has a complete Component lifecycle which might help you:

Try this:

  1. do not directly calculate your screen changes, but do this in the updateDisplayList method.
  2. When receiving the ResizeEvent, only call the invalidateDisplayList() method, which sets a framework flag that will trigger execution of updateDisplayList()

You can read more about the Flex3 Component lifecycle here: http://www.dlgsoftware.com/primers/Primer_on_Flex3_Component_Lifecycle.htm

like image 1
Daniel Rijkhof Avatar answered Oct 24 '22 07:10

Daniel Rijkhof