View Full Version : DisplayObject must be a child of the caller
texastoast
06-08-2007, 05:58 PM
Hi all, hope you can assist me with this problem I'm having. I'm basically trying to refresh a jpg image every second from within my flash project. The code so far:
//This function is called from the loader's event listener.
//It moves the loaded image into the appropriate container for display
function imgLoaded(event:Event):void
{
movie.get_picture.addChild(l.content);
};
//This is the function called by the timer that performs all the above
//loading steps each time the timer ticks. This updates the image once per
//second.
function refresh_url(event:TimerEvent){
var unique = new Date().getTime();
var url:String = "http://www.live-photo.com/asheville-.jpg?" + unique;
var urlReq:URLRequest = new URLRequest(url);
l.load(urlReq);
l.contentLoaderInfo.addEventListener(Event.COMPLET E, imgLoaded);
};
//Create the timer object that will call the function to update the image
//object once per second.
var myTimer = new Timer(1000);
//Add an event listener to the timer to refresh the image every time the timer
//ticks
myTimer.addEventListener("timer",refresh_url);
//Start the timer
myTimer.start();
The image refreshes, but only on what looks like every 2nd call to the refresh_url function. It will load the image once, then it will throw an error:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::Loader/flash.display:Loader::_load()
at flash.display::Loader/load()
at map_project1_fla::MainTimeline/refresh_url()
at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
at flash.utils::Timer/flash.utils:Timer::tick()
And then it will load the picture, then it will throw the error, then load, then throw, etc...
What do I need to do to avoid this error? Thanks in advance.
panel
06-11-2007, 02:18 PM
My gues would be to stop timer in refresh_url function and start it when load is complette or create variable isLoaded and add check it value in refresh_url function.
BTW
you don't have to add listener to every time you run function.
l.contentLoaderInfo.addEventListener(Event.COMPLET E, imgLoaded);
TwoManStudios
07-21-2007, 10:56 AM
Im having the same problem as person above, and was wondering if anyone ever figured out the solution?
texastoast
08-03-2007, 03:57 PM
The solution for me was to wrap the whole thing in error handling code. This is still causing me a problem though. See http://www.actionscript.org/forums/showthread.php3?p=638697 for the revised code and the new problem.
gabi_poa
08-10-2007, 04:33 PM
Try not to add the Loader.content as a child of you container.
Follows teh code of a similar app, wich uses Timer instead of Date
var ticker:Timer = new Timer(5000);
var count:uint;
var arArray:Array=["bicho-1.gif","bicho-2.gif","bicho-3.gif"];
var ldLoader:Loader = new Loader();
var URLReq:URLRequest;
var container:Sprite = new Sprite();
addChild(container);
ticker.addEventListener(TimerEvent.TIMER, onTick);
ldLoader.contentLoaderInfo.addEventListener(Event. COMPLETE, carregou);
ticker.start();
function onTick(event:TimerEvent):void {
if (count<arArray.length) {
URLReq = new URLRequest(arArray[count]);
try {
ldLoader.load(URLReq);
}
catch (error:ArgumentError) {}
catch (error:MemoryError) {}
catch (error:SecurityError) {}
catch (error:TypeError) {}
catch (error:Error) {}
trace(arArray[count])
count++;
}
}
function carregou(event:Event):void {
container.addChild(ldLoader);
}
texastoast
08-10-2007, 06:14 PM
Thanks, I will try that.
tim_m
10-09-2007, 10:57 PM
Hi texastoast,
I had the same problem. Realise this is a bit late - but might be useful to others.
I got it to work by registering a variable to the loader.content, calling unload() on the loader and then adding the content to a displayObject.
If you try calling Loader.load() or Loader.unload() after you have added the Loader.content directly to another displayObject, the error you got occurs.
Presumably this is because the load() & unload() methods try to remove the content from the Loader - & if it's already been removed (when added to another displayObject), the error happens.
your imgLoaded function would look like:
function imgLoaded(event:Event):void
{
var theImage:DisplayObject = event.target.content;
l.unload();
movie.get_picture.addChild(theImage);
}
gosUber
11-09-2007, 01:27 PM
Solved my problem with one line of code, tim_m. I was wondering why it was giving that error.
hardyvoje
01-24-2008, 02:27 PM
Alternative solution is to add:
var myLoader:Loader = new Loader();
before every
myLoader.load(); // call
this was the easiest solution for me.
joshspoon
05-06-2008, 10:56 PM
you have to turn that content into bitmapdata
put it in a new bitmap
then addchild
private function onComplete(evt:Event):void
{
var bmd = Bitmap(evt.target.loader.content).bitmapData;
var tmpBmp:BitmapData = bmd.clone()
var bit:Bitmap = new Bitmap(tmpBmp, PixelSnapping.AUTO, true);
addChild(bit);
}
gellm
07-11-2008, 04:03 AM
(as3)
(Answer may be useful to someone, somewhere...)
I got a bunch of "ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller." messages where I was trying to load swf files into a Sprite (a display object container) and overwrite them each time i clicked on different links.
The program was working fine - then I travelled to a different frame and back again and the code stopped working. The resolution...
//I was using a variable to refer to a display object, and it needed to be made null when i was finished with it so that when i returned to the script later the old variable was not floating around still. I used to do a lot of programming in director with framescripts which lose all their variable values when you leave the frame so this was a surprise in flash as3 that they hang around afterwards.
var page_Reference:DisplayObject; //was declared like so and used later on in a function...
//(str_FocusButton_PageUrl is a string pointing to my .swf file)
//eventually a click eventuates in this function being called.
function loadSubCatPage(callingEvent:Event):void
{
var pageLoader:Loader = new Loader();
var PageUrlReq:URLRequest = new URLRequest(Swf_folder + str_FocusButton_PageUrl);
pageLoader.load(PageUrlReq);
pageLoader.name = "page";
//Remove the current page. Problem occurred here when I returned from
//a different script and found page_Reference still had an old value in it.
//So the caller: Ref_browserMc was not a parent of the
//display object: page_Reference. Or something like that.
if (page_Reference != null) {
trace("Removing page... Ref_browserMc=" + Ref_browserMc);
Ref_browserMc.removeChild(page_Reference);
}
page_Reference = Ref_browserMc.addChild(pageLoader);
}
...so I had to declare my variable as null when the script returned from another frame.
var page_Reference:DisplayObject; = null;
Sorry if that doesn't make sense, im just trying to give something back.
dkoslu
09-17-2008, 10:23 PM
Hi, I ran into this same problem (and other variations of it). I am not a Flash/AS expert by any means, so it might be that I am not using the Loader class properly, but I did some straightforward experiments and I think this may be a bug in the Flash runtime.
What I noticed is this: you are not able to simply reparent the Loader's "content" object to your display list and then re-use the Loader. You may think you are moving the content (eg, a Bitmap) on to the display list, but in fact the Loader continues to reference it through its "content" field even though it is no longer a child of the Loader.
That is, if your event listener looks something like this (not actual code):
function initListener(e:Event):void {
addChild(loader.content); // or addChild(e.target.content)
trace(loader.numChildren); // 0
trace(loader.content.toString()); // [class Bitmap]
}
The content is put into the DisplayObject hierarchy but Loader still holds on to it. Re-using the Loader object then causes the Exception.
I couldn't solve this through unload() or other means; even creating a new loader each time had some similar kind of problem. I don't remember the details off hand, but I think there may be a problem with garbage collecting Loaders (Loader and LoaderInfo have a circular reference) and this leads to a slow memory leak. (I saw a complaint on this on this or some other forum.)
Anyway, I think this legitimately points to an error in Flash and if I knew how to report it, I would.
The alternative to this is to simply add the Loader itself to your display list. (I think a previous reply said the same thing) You can then reuse the Loader and it manages itself correctly and predictably.
Rocketboy
10-15-2008, 04:18 PM
There is indeed many problems with Flash being able to unload things, and there is a great article by GSkinner on the issue here: http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html
When you say The alternative to this is to simply add the Loader itself to your display list. (I think a previous reply said the same thing) You can then reuse the Loader and it manages itself correctly and predictably.
Just what exactly do you mean by that? Can you give an example? Does adding the Loader to the display list add the loaded content to the display list aswell?
quocdai
10-18-2008, 10:05 AM
stop();
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.DisplayObject;
hidetrangchu_hide.addEventListener(MouseEvent.MOUS E_MOVE, hidetrangchuClick);
function hidetrangchuClick(e:MouseEvent):void
{
addChild(home);
removeChild(dichvu);
removeChild(doitac);
removeChild(gioithieu);
SoundMixer.stopAll();
}
hidegioithieu_hide.addEventListener(MouseEvent.MOU SE_MOVE, hidegioithieuClick);
function hidegioithieuClick(e:MouseEvent):void
{
addChild(gioithieu);
removeChild(home);
removeChild(dichvu);
removeChild(doitac);
SoundMixer.stopAll();
}
hidedichvu_hide.addEventListener(MouseEvent.MOUSE_ MOVE, hidedichvuClick);
function hidedichvuClick(e:MouseEvent):void
{
addChild(dichvu);
removeChild(gioithieu);
removeChild(doitac);
removeChild(home);
SoundMixer.stopAll();
}
hidedoitac_hide.addEventListener(MouseEvent.MOUSE_ MOVE, hidedoitacClick);
function hidedoitacClick(e:MouseEvent):void
{
addChild(doitac);
removeChild(home);
removeChild(dichvu);
removeChild(doitac);
SoundMixer.stopAll();
}
homeagain.addEventListener(MouseEvent.CLICK, hidetrangchuClickagain);
function hidetrangchuClickagain(e:MouseEvent):void
{
removeChild(dichvu);
removeChild(doitac);
removeChild(gioithieu);
addChild(home);
SoundMixer.stopAll();
}
gioithieuagain.addEventListener(MouseEvent.CLICK, hidegioithieuClickagain);
function hidegioithieuClickagain(e:MouseEvent):void
{
SoundMixer.stopAll();
addChild(gioithieu);
removeChild(home);
removeChild(dichvu);
removeChild(doitac);
}
dichvuagain.addEventListener(MouseEvent.CLICK, hidedichvuClickagain);
function hidedichvuClickagain(e:MouseEvent):void
{
addChild(dichvu);
removeChild(gioithieu);
removeChild(doitac);
removeChild(home);
SoundMixer.stopAll();
}
doitacagain.addEventListener(MouseEvent.CLICK, hidedoitacClickagain);
function hidedoitacClickagain(e:MouseEvent):void
{
removeChild(home);
removeChild(gioithieu);
removeChild(dichvu);
SoundMixer.stopAll();
}
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at update17_10_2008_new_fla::MainTimeline/hidetrangchuClick()
creynders
10-18-2008, 10:08 AM
There is indeed many problems with Flash being able to unload things, and there is a great article by GSkinner on the issue here: http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html
When you say
Just what exactly do you mean by that? Can you give an example? Does adding the Loader to the display list add the loaded content to the display list aswell?
Yes. The Loader object is a proxy for the actual content. So you can add the Loader object itself to the display list.
Personally I'm not a fan of doing that, it doesn't seem... clean, or something.
Rocketboy
10-22-2008, 12:37 AM
Yes. The Loader object is a proxy for the actual content. So you can add the Loader object itself to the display list.
Hold on a sec, I'm trying to do this and getting a type coercion error, as I would have expected. Are you sure you an do this, what am I doing wrong here?
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, loaded);
private function loaded(e:Event=null)
{
holder.addChild(e.target);
}
maskedMan
10-22-2008, 12:46 AM
Hold on a sec, I'm trying to do this and getting a type coercion error, as I would have expected. Are you sure you an do this, what am I doing wrong here?
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, loaded);
private function loaded(e:Event=null)
{
holder.addChild(e.target);
}
You're not recasting the e.target as a Loader object. Until you cast it, e.target can have a habit of just calling itself "Object" and when you add it to the display list without the proper casting, the program whines. Either that, or you're trying to add loader.loaderContentInfo to the display list, which is even more problematic. If you only have the one loader object, you could just do holder.addChild(loader); and it would work as expected.
The biggest prejudice I have against adding a Loader object to the display list is that while it functions as a basic proxy, it completely lacks many functions and properties of display objects that you might like to manipulate. useHandCursor? Nope. gotoAndStop()? Nope. Creynders has it right... it's not clean, and it's probably not worth your time. Once the object has finished loading, just add the loader.content to the display list.
|
vBulletin® v3.8.5, Copyright ©2000-2010, Jelsoft Enterprises Ltd.