one of those little things that are not clearely documented or explained anywhere on the Adobe flash documentation..
I was calling a function to load an image and add it to stage, and everytime I called that image, I was getting this error:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller
after 2 hours of trials and errors and 1 hour of web search, I finally found the answer below.
within this code:
package{
import flash.display.DisplayObject;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.net.URLRequest;
public class img extends Sprite
{
private var loader:Loader = new Loader();
...
..
public function loadBgImage():void
{
var randDate:Date = new Date();
if (holder.getChildByName("bgImg"))
{
if (holder.contains(holder.getChildByName("bgImg")))
holder.removeChild(holder.getChildByName("bgImg"))
}
var request:URLRequest = new URLRequest("images/bg.jpg?randPath="+randDate.getTime());
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
loader.load(request);
}
public function completeHandler(e:Event):void
{
var bm:Bitmap = e.target.contentas Bitmap;
bm.smoothing = true;
var sp:Sprite = new Sprite();
sp.addChild(bm);
sp.name = "bgImg";
holder.addChild(sp);
}
}
it works fine the first time.. however, while in runtime, if you try to call loadBgImage() again, you will get this error:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller
and after lots of research, it turns out that this occurs when the Loader is declared as a global variable in the class (i.e: when we don’t say :var loader:Loader = new Loader() every time we call the function) and the load() function is called again after the first load
when the COMPLETE event is fired, if we add the loader to stage as a e.target.content, then we are actually adding the only instance of that loader (Loader is a DisplayObject after all)
so, if we try to remove it in the load function and remove it before calling the function again:
holder.removeChild(holder.getChildByName("bgImg"))
then we are actually removing the only instance of that loader, so when we try to call it again onloader.load(), the instance is not found..
Thanks to the fine gentelmen at Actionscript.or, this discussion solved my problem:
http://www.actionscript.org/forums/archive/index.php3/t-138634.html
so, the best way to do this is:
1- cast the content to a display Object, and unload the loader, and then add the newly created display Object to the stage : see below
public function completeHandler(e:Event):void
{
var theImage:DisplayObject = e.target.content;
loader.unload()
var bm:Bitmap = theImage as Bitmap;
bm.smoothing = true;
var sp:Sprite = new Sprite();
sp.addChild(bm);
sp.name = "bgImg";
holder.addChild(sp);
}
or, the second way to do this is:
2- get the bitmap data of that loaded content, make a clone, instantiate a new bitmap based on that bitmap data, and add that one to stage like this:
public function completeHandler(e:Event):void
{
var bm:Bitmap = new Bitmap(((e.target.content as Bitmap).bitmapData as BitmapData).clone());
bm.smoothing = true;
var sp:Sprite = new Sprite();
sp.addChild(bm);
sp.name = "bgImg";
holder.addChild(sp);
}