2 Replies Latest reply on Sep 28, 2009 6:12 AM by Harm Meijer

    Unable to access children (numchildren=-1) of SWFLoader in the complete or init event

    Harm Meijer

      Trying to set a label of a loaded flash (that is public), Works fine if I call a timer and wait for 2 seconds. Then I tried to do it the "right" way and it fails. (see example code) Aparnently the loaded flash (type FlashLoader) has a child (type SystemManager) with numChildren set to -1 when called from the event.

       

      Tried both init and complete event but no workie.
      http://livedocs.adobe.com/flex/3/langref/mx/controls/SWFLoader.html#summaryTableEvent
      init: Dispatched when the properties and methods of a loaded SWF file are accessible.
      complete: Dispatched when content loading is complete.

       

      Here is the example code:
      the swf to be loaded only has a label with id innerLabel and is named inner.swf

       

      <?xml version="1.0" encoding="utf-8" ?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init();">
      <mx:Script>
      <![CDATA[
      import flash.display.DisplayObject;
      import flash.display.DisplayObjectContainer;
      import flash.events.TimerEvent;
      import flash.utils.Timer;
      import mx.controls.Label;
      import flash.utils.*;
      import mx.controls.SWFLoader;
      import mx.core.Container;
      import mx.core.FlexLoader;
      import mx.managers.SystemManager;

       

      public var errors:Array = new Array();
          public var ld:SWFLoader = new SWFLoader();
      public function init():void {
              ld.load("inner.swf");
              ld.addEventListener(Event.COMPLETE, setInnerLabel);
              this.addChild(ld);
             
              // COMMENT OUT THE ADDEVENTLISTENER AND UNCOMMENT THE NEXT 3 LINES AND IT WORKS
              // LIKE A CHARM
              //var t:Timer = new Timer(2000, 1);
              //t.addEventListener(TimerEvent.TIMER, setInnerLabel);
              //t.start();
      var doneTimer:Timer = new Timer(3000, 1);
      doneTimer.addEventListener(TimerEvent.TIMER, checkDone);
      doneTimer.start();
      }
      public function checkDone(o:Object):void {
      if (this.errors.length != 0) {
      trace(this.errors.join("\n"));
      }else {
      trace("Completed without errors");
      }
      }

       

          public function setInnerLabel(o:Object):void {
              var l:Label = getObjectsByProperty(this, "id", "innerLabel", null)[0] as Label;
              if (l == null) {
                  errors.push("Unexpected innerLabel did not return label......");
              } else { l.text = "getbyid OK"; }
          }
              //{ region functions for getElementById
              public function getObjectsByProperty(startFrom:DisplayObjectContainer,
                                                      propertyName:String,
                                                      propertyvalue:String,
                                                      arrRet:Array=null):Array {
                  if (arrRet == null) {
                      arrRet = new Array();
                  }
                  // in case you pass a null
                  if (startFrom == null) {
                      return arrRet;
                  }
                  if (startFrom.hasOwnProperty(propertyName)) {
                      if (startFrom[propertyName] == propertyvalue) {
                          arrRet.push(startFrom);
                      }
                  }
                  //trace("HOW MANY CHILDREN: " + new String(startFrom.numChildren));
                  traceElem(startFrom);
                  for (var i:int = 0; i < startFrom.numChildren; i++) {
                      traceElem(startFrom.getChildAt(i));
                      if (startFrom.getChildAt(i) is DisplayObjectContainer) {
                          var tmpArr:Array = getObjectsByProperty(startFrom.getChildAt(i) as DisplayObjectContainer,
                                  propertyName, propertyvalue, arrRet);
                          arrRet = tmpArr;
                      }else {
                          trace("THE FOLLOWING WAS NOT A DISPLAYOBJECTCONTAINTER:");
                          traceElem(startFrom.getChildAt(i));
                      }
                  }
                  return arrRet;
              }
             
              private function traceElem(elem:Object):void {
                  var x:XML = describeType(elem);
                  var s:String = "Got an element of type: " + x.attribute("name").toString();
                  for (var i:int = 0; i < x.child("method").length(); i++) {
                      if (x.child("method")[i].attribute('name').toString() == "getChildAt") {
                          s = s + "\n\t\t\tSupports getChildAt";
                      }
                  }
                  for (i = 0; i < x.child("accessor").length(); i++) {
                      if (x.child("accessor")[i].attribute('name').toString() == "numChildren") {
                          s = s + "\n\t\t\tSupports numChildren";
                          s = s + "\n\t\t\tChildren: " + new String((elem.numChildren));
                      }
                  }
                  trace(s);
              }
              //} endregion
      ]]>
      </mx:Script>
      </mx:Application>