6 Replies Latest reply on Nov 2, 2010 12:41 PM by Devtron

    Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of

    Devtron Level 3

      Hello

       

      I am having some trouble adding UI controls dynamically. Mostly with radio buttons.

       

      Here is an example that demonstrates my problem:

      <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"
          creationPolicy="all"
          >
         
          <fx:Script>
              <![CDATA[ 
                  import mx.containers.Form;
                  import mx.containers.Panel;
                  import mx.controls.Label;
                  import mx.controls.NumericStepper;
                  import mx.controls.RadioButton;

       

                  private var theChar:String = "B";
                 
                  protected function btnAdd_clickHandler(event:MouseEvent):void
                  {                           
                     
                      var theForm:Form = new Form();               
                      theForm.label = theChar;
                     
                      //1. Label
                      var myLabel:Label = new Label();
                      myLabel.text = "My Label";
                      myLabel.width=120;
                      theForm.addChild(myLabel);
                     
                      //2. Numeric Stepper
                      var myNumStepper:NumericStepper = new NumericStepper();
                      myNumStepper.id = "numPointHigh" + theChar;
                      myNumStepper.name = "numPointHigh" + theChar;
                      myNumStepper.minimum = 0;
                      myNumStepper.maximum = 120;
                      myNumStepper.width = 50;
                      myNumStepper.height = 30;
                      theForm.addChild(myNumStepper);
                     
                      //3. radio button
                      var myRadioButton:RadioButton = new RadioButton;
                      myRadioButton.id = "myRadioButton" + theChar;
                      myRadioButton.name = "myRadioButton" + theChar;
                      myRadioButton.label = "my radio button";
                      myRadioButton.selected = true;
                      theForm.addChild(myRadioButton);
                     
                      //4. Panel
                      var thePanel:Panel = new Panel();
                      thePanel.width = 300;
                      thePanel.height = 475;
                      thePanel.name=theChar;
                      thePanel.title = "My Profile Panel";
                      thePanel.setStyle("backgroundColor", "blue");
                     
                      //add the form to the panel
                      thePanel.addChild(theForm);
                     
                      //add the Panel to the list control
                      myList.addChild(thePanel);
                     
                  }
                 
                  protected function btnClear_clickHandler(event:MouseEvent):void
                  {
                      var numChildren:Number = myList.numChildren;
                      for(var i:Number=numChildren - 1; i > -1; i--){
                          myList.removeChildAt(i);
                      }
                  }
                 
              ]]>
          </fx:Script>
         
          <mx:VBox width="100%">
              <mx:List id="myList" />
              <mx:Button id="btnAdd" label="Add a panel" click="btnAdd_clickHandler(event)" color="black"/>
              <mx:Button id="btnClear" label="Clear" click="btnClear_clickHandler(event)" color="black" />
          </mx:VBox>
         
      </s:Application>

       

       

       

      ^ Run that. Click the "Add a panel" button. Then click "Clear". Then click the "Add a panel" button again. You will see the error:

      ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
          at flash.display::DisplayObjectContainer/getChildIndex()
          at mx.core::Container/getChildIndex()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core \Container.as:2833]
          at mx.containers::Panel/getChildIndex()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\co ntainers\Panel.as:1174]
          at mx.controls::RadioButtonGroup/breadthOrderCompare()[E:\dev\4.0.0\frameworks\projects\fram ework\src\mx\controls\RadioButtonGroup.as:600]
          at mx.controls::RadioButtonGroup/breadthOrderCompare()[E:\dev\4.0.0\frameworks\projects\fram ework\src\mx\controls\RadioButtonGroup.as:611]
          at mx.controls::RadioButtonGroup/breadthOrderCompare()[E:\dev\4.0.0\frameworks\projects\fram ework\src\mx\controls\RadioButtonGroup.as:611]
          at Array$/_sort()
          at Array/http://adobe.com/AS3/2006/builtin::sort()
          at mx.controls::RadioButtonGroup/http://www.adobe.com/2006/flex/mx/internal::addInstance()[E:\dev\4.0.0\frameworks\projects \framework\src\mx\controls\RadioButtonGroup.as:465]
          at mx.controls::RadioButton/addToGroup()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\c ontrols\RadioButton.as:574]
          at mx.controls::RadioButton/commitProperties()[E:\dev\4.0.0\frameworks\projects\framework\sr c\mx\controls\RadioButton.as:514]
          at mx.core::UIComponent/validateProperties()[E:\dev\4.0.0\frameworks\projects\framework\src\ mx\core\UIComponent.as:7772]
          at mx.managers::LayoutManager/validateProperties()[E:\dev\4.0.0\frameworks\projects\framewor k\src\mx\managers\LayoutManager.as:572]
          at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\frame work\src\mx\managers\LayoutManager.as:730]
          at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projec ts\framework\src\mx\managers\LayoutManager.as:1072]

       

       

      I do not understand why I cannot re-add the radio button? If you comment out the code for the radio button (comment section #3.) you can re-add the panels easily. It is only happening when I have radio buttons being added to the form/panel.

       

      Why is this happening and how do I fix it? Why is this only happening to radio buttons? I thought I had this fixed

        • 1. Re: Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of
          Flex harUI Adobe Employee

          List is not a container and doesn't expect arbitrary addding of children.

          • 2. Re: Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of
            Devtron Level 3

            ^ well, okay, but that's not the problem.

             

            here, i removed list and replaced with Panel. same problem on the radio buttons.

             

             

             

            <s:Application
                xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:containers="com.dougmccune.containers.*"
                xmlns:mx="library://ns.adobe.com/flex/mx"
                creationPolicy="all"
                >
               
                <fx:Script>
                    <![CDATA[ 
                        import mx.containers.Form;
                        import mx.containers.Panel;
                        import mx.controls.Label;
                        import mx.controls.NumericStepper;
                        import mx.controls.RadioButton;

             

                        private var theChar:String = "B";
                       
                        protected function btnAdd_clickHandler(event:MouseEvent):void
                        {                           
                           
                            var theForm:Form = new Form();               
                            theForm.label = theChar;
                           
                            //1. Label
                            var myLabel:Label = new Label();
                            myLabel.text = "My Label";
                            myLabel.width=120;
                            theForm.addChild(myLabel);
                           
                            //2. Numeric Stepper
                            var myNumStepper:NumericStepper = new NumericStepper();
                            myNumStepper.id = "numPointHigh" + theChar;
                            myNumStepper.name = "numPointHigh" + theChar;
                            myNumStepper.minimum = 0;
                            myNumStepper.maximum = 120;
                            myNumStepper.width = 50;
                            myNumStepper.height = 30;
                            theForm.addChild(myNumStepper);
                           
                            //3. radio button
                            var myRadioButton:RadioButton = new RadioButton;
                            myRadioButton.id = "myRadioButton" + theChar;
                            myRadioButton.name = "myRadioButton" + theChar;
                            myRadioButton.label = "my radio button";
                            myRadioButton.selected = true;
                            theForm.addChild(myRadioButton);
                           
                            //4. Panel
                            var thePanel:Panel = new Panel();
                            thePanel.width = 300;
                            thePanel.height = 475;
                            thePanel.name=theChar;
                            thePanel.title = "My Profile Panel";
                            thePanel.setStyle("backgroundColor", "blue");
                           
                            //add the form to the panel
                            thePanel.addChild(theForm);
                           
                            //add the Panel to the list control
                            myContainer.addChild(thePanel);
                           
                        }
                       
                        protected function btnClear_clickHandler(event:MouseEvent):void
                        {
                            var numChildren:Number = myContainer.numChildren;
                            for(var i:Number=numChildren - 1; i > -1; i--){
                                myContainer.removeChildAt(i);
                            }
                        }
                       
                    ]]>
                </fx:Script>
               
                <mx:VBox width="100%">
                    <mx:Panel id="myContainer" />
                    <mx:Button id="btnAdd" label="Add a panel" click="btnAdd_clickHandler(event)" color="black"/>
                    <mx:Button id="btnClear" label="Clear" click="btnClear_clickHandler(event)" color="black" />
                </mx:VBox>
               
            </s:Application>

             

             

             

            Any idea why radio buttons causing this to happen? If I comment out the radio button, this works fine. This is really baffling me.

             

            The exception is thrown when the dynamically created panel (thePanel) is added to the main Panel (myContainer):

            myContainer.addChild(thePanel); <--- causes the exception!

             

            ^ Why would radio buttons make a difference on "thePanel"?? How can I enforce parent-child relationship, explicitly? .parent is read-only

            • 3. Re: Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of
              JeffryHouser Level 4

              I answered over on stack overflow.  Make sure your Radio Buttons are in a Radio Button Group and your error goes away.

              • 4. Re: Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of
                Devtron Level 3

                ^ Wow, Thank you Jeffry! Originally I tried to use the RadioButtonGroup object, but couldnt get it to work. I was trying to assign a name to it, and was use the .groupName property on the radiobutton, instead of "group", as you pointed out.

                 

                One question...what is the purpose of using the Math function on the ID assignment? I know ID's should be unique, but I need to reference these panels dynamically. We are using the Alphabet to limit the users to 26 panels, so I can reference my panel objects by Alphabet index. That is a hack but saves me the trouble of doing it manually. I was just curious as to the reasoning behind the Math operation? I know it's good practice, but any other specific reasons?

                 

                Thanks heaps man!

                • 5. Re: Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of
                  JeffryHouser Level 4

                  The Math / Random function had no point.  I was just testing something with naming before I came onto the real solution.  In your sample code, the "theVar" value never changes; so I Wanted to make sure the issue was not with the radio buttons having the same name.

                   

                  If you need to access a bunch of similar items, like this, I would just put them in an array and process them in a loop as opposed to trying to access them individually by name.  Any "item specific" processing I Would encapsulate into a single component with all the relevant elements instead of creating them manually in your ActionSCript method and doing a lot of 'addChild' stuff.

                  • 6. Re: Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of
                    Devtron Level 3

                    Wow, thanks. I figured the Math function was for debugging, I just wasnt sure if I should study it. Thanks for the clarification.

                     

                    I agree with you 100%. I originally had 26 panels defined in MXML, because I did not want to try to do it in ActionScript. Now, I am in the situation where I am going to use ActionScript over MXML to do this. The show stopper was this problem with the radio buttons.

                     

                    I have now removed my 26 panels from MXML and create them dynamically, through ActionScript loops. It is nice and I like it. I did not originally do this because Ive had such trouble sizing and positioning things through pure ActionScript. I actually like using this better and wish I had done it from the beginning.

                     

                    But I have learned very much, thanks for taking the time to explain this so well...