views:

601

answers:

5

Happy Pre-Halloween everyone :)

My issue today is a DisplayObject error I'm getting when remove a child object. I have code that will launch(addChild) a video container and video controls as well as add a close button. Now the close button works fine and everything, removing the video and controls and I'm able to choose another video again, but when you click close a 2nd time I get this error:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/removeChild()

So I've narrowed down the problem to where I remove the videoContainer (which holds the video object)

My code to play the videos:

public function videoSwitch(videoName):void
{
 nv.closeOut();
 nv.resetNav = false;

    if (!videoPlaying)
    {
        vc = new VideoClass(videoName, videoHolder);
     vc.addEventListener("KillMovie", removePlayer);
     container.addChild(videoContainer);
     container.addChild(vc);
     //container.addChildAt(videoContainer, 1);
     //container.addChildAt(vc, 2);
     videoPlaying = true;
     closeVideo();
    }

    else if (videoPlaying)
    {
     vc.clearSource();
     container.removeChild(videoContainer);
     container.removeChild(vc);

     vc = new VideoClass(videoName, videoHolder);
     vc.addEventListener("KillMovie", removePlayer);
     container.addChild(videoContainer);
     container.addChild(vc);
     //container.addChildAt(videoContainer, 1);
     //container.addChildAt(vc, 2);
     closeVideo();
    }
     trace("videoPlaying = "+videoPlaying+"\r");
}

The close out video player code: You can see in my comments other code I tried, but still getting the error.

function closeVideo():void 
{
    closeBtn.visible = true;
    closeBtn.x = 770;
    closeBtn.y = 20;
    closeBtn.buttonMode = true;
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
     vc.clearSource();
     container.removeChild(videoContainer);
     //container.removeChildAt(videoContainer, 1);
     container.removeChild(vc);
     videoPlaying = false;
     closeBtn.visible = false;
    }
}

Now my movie works fine, but I'm worried that this error happening in the background (and showing up in my output window) will eventually cause a problem else where :(

Thanks in advance for any eyes on this one! :)


UPDATE: FIXED! The problem was I remove the kill VC listener, but forgot to remove the stupid Close Button Mouse_Event listener :(

function addCloseButton():void 
{
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
     videoPlaying=false;
       vc.clearSource();
     removeContainerChildren(); // <- thx Joel!
     closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
     //^ Forgot this line - thx Jotham!
     container.removeChild(closeBtn);
    }
}

Don't know if this graphic helps but: alt text

+1  A: 

Try this:

 container.removeChild(container.videoContainer);
 container.removeChild(container.vc);
Preston
Still getting that error, but movie still works fine tho... wondering if I really should be worried about this hmmz
Leon
trying this now too: if(videoContainer.parent != null) videoContainer.parent.removeChild(videoContainer); but same results
Leon
+2  A: 

here is one approach to avoid the error:

 public function videoSwitch(videoName):void
 {
  nv.closeOut();
  nv.resetNav = false;

  if (videoPlaying)
  {
   vc.clearSource();
   removeContainerChildren()
  }

  addContainerChildren();
  closeVideo();
 }

 protected function removeContainerChildren():void
 {
  if(container.contains(videoContainer))
   container.removeChild(videoContainer);
  if(container.contains(vc))
  {
   container.removeChild(vc) 
   vc.removeEventListener("KillMovie", removePlayer)
  }
 }

 protected function addContainerChildren():void
 {
  videoPlaying = true;
  vc = new VideoClass(videoName, videoHolder);
  vc.addEventListener("KillMovie", removePlayer, false, 0, true); 
  container.addChild(videoContainer);
  container.addChild(vc);

  trace("videoPlaying = "+videoPlaying+"\r");
 }
Joel Hooks
Still getting error, but movie still working fine... I did notice something now, when I play 1 video, close it play another video close it I get 1 error message. Not refreshing I play another video again and close it I get 2 error messages the same, 3 videos 3 error messages trace out, a hint maybe?
Leon
+1  A: 

I have a feeling that it is some other piece of code causing the actual problem. This error would make sense if the videuPlaying variable got changed somewhere else so that you were removing something that did not exist as yet. Maybe check that you are not changing this variable somewhere else.

Allan
Yeah I think there is something else I'm not looking at that is still connected here, tried 3 different ways, all which work great, but that error still lingers
Leon
+1  A: 

Do you ever remove the listener? You could well be having it fire multiple times.

Jotham
That was it OMG! Forgot to remove the closeButtonClicked Event! /facepalmremoveContainerChildren(); closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);ontainer.removeChild(closeBtn);
Leon
+1  A: 

This is another uber hacky way of doing this, not usually recommended but it will definitly insure that the videoContainer/vc is removed from whichever DisplayList it is on.

private function removeFromStack(target:DisplayObject):void
{
 if (target.parent)
  target.parent.removeChild(target);
}

private function removeVideo():void
{
    removeFromStack(vc);
    removeFromStack(videoContainer);
    vc = videoContainer = null;
}

Just to re-itterate, this is not the preferred way, but it will work without errors. If you start to get a "cannot access null object reference" error, then as previous people have suggested, event listeners or some other dependancies are still held by the DisplayObject's in question.

Hope this helps

I forgot to remove the closeButton event listener! closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
Leon