Search code examples
actionscript-3apache-flexviewstack

How to run a function after the canvas has changed in ActionScript 3.0?


Please understand: I am a total beginner at Actionscript and anything like Actionscript, and though I generally have some idea of what I'm doing as a programmer, I'm having some setbacks in self-learning this language and Flex Builder. Right now I'm trying to make a very simple implementation where a label effectively has its text added to multiple times over the first few seconds that the program is run. The problem I'm running into is that I can't just put all that into one function + one call on that function, as changes to the label's text are apparently not seen until that function runs its full course.

So I tried using a viewstack and cloning the canvas a few times, giving each canvas's version of that label a different bit of text. Then I set the initialize function for the viewstack to change the canvases on regular intervals over the first few seconds. But that didn't work either, as the difference isn't seen until the function runs its full course.

So then I tried putting function calls on the individual canvases' initialize attributes, and those functions aren't being called at all apparently.

What the heck? I know this probably isn't even the way that you're supposed to animate something in ActionScript or Flex, but I still would like to know how to approach the problem this way for future reference. What am I missing? Thanks!


Solution

  • As you've noticed, changes to the displayed output of your program can't happen in the middle of executing a function that you've written. ActionScript is single-threaded, which means that none of the framework code that updates the screen can run while your function is running.

    If you're interested in learning exactly what happens in order to update the screen, do a search for "flex component lifecycle" and read some of the stuff you find. It's a bit advanced, but it was the thing that really helped me understand how the Flex framework works.

    Anyway, on to your real question - how to animate something. There are many ways, but for your case of progressively adding text to a label, I'd probably use the Timer class.

    Here is an example:

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    
      <fx:Script>
        <![CDATA[
          import mx.events.FlexEvent;
    
          private var timer:Timer;
          private var words:Array = ["The", "quick", "brown", "fox"];
    
          private function startTimer(event:FlexEvent):void
          {
            timer = new Timer(1000, 1);
            timer.addEventListener(TimerEvent.TIMER, updateText);
            timer.start();
          }
    
          private privatefunction updateText(event:TimerEvent):void
          {
            theLabel.text += words.shift() + " ";
    
            if (words.length > 0)
            {
              timer.reset();
              timer.start();
            }
          }
        ]]>
      </fx:Script>
    
      <s:Label id="theLabel" text="" creationComplete="startTimer(event)"/>
    
    </s:Application>