10 Replies Latest reply on Sep 16, 2009 4:35 AM by SiHoop

    Using containers

    SiHoop Level 1

      I havea container question that has been bothering me for a long time: How am I supposed to add an instance of a class to the stage? In the file below I have 3 ways to add an instance of the class Shapes (listed below). Approach 1 uses a UIComponent named container. This works fine but feels wrong as I am having to add a component. Approach 2 uses rawChildren. This works fine but it feels like a 'work around'. Approach 3 (this.addChild(shape);) fails and gives me an error, although it 'feel right'.

       

      Is Approach 1 the right way to add instances to the stage or is there a better way?

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
          <mx:Script>
              <![CDATA[
      private var shape:Shapes
      public function init():void{
          shape=new Shapes();

          container.addChild(shape);
          //rawChildren.addChild(shape);

          //this.addChild(shape);
      }
              ]]>
          </mx:Script>
      <mx:UIComponent id="container" />
      </mx:Application>

       

      package {
          import flash.display.Shape;
          import flash.display.Sprite;
          public class Shapes extends Sprite {
              public function Shapes() {
                 var child:Shape = new Shape();
                  child.graphics.beginFill(0xFFCC00);
                  child.graphics.lineStyle(0);
                  child.graphics.drawRect(0, 0, 50, 50);
                  child.graphics.endFill();
                  addChild(child);
              }
          }
      }

        • 1. Re: Using containers
          ShardulSingh Level 3

          As you are saying that you want to add child to the Stage,then its bit confusing from the perspective of flex. Because at stage the only one thing is added and that is our flex Application. Now the thing is that as you have used the I<mx:UIComponent/> tag inside the Application it means you are adding the UIComponent on the application and inside that you are adding the shapes.But if you will write 'this.addChild' then here 'this' refers to the Application so it is not a good approach. Insted you should take the Canvas instead of the UIComponent and then you should add these shapes to that canvas. Like

           

          container.rawChildren.addChild(shape);

           

          so that if you want to add any other components(which are not object of your shapes class then) to the container then you can directly use

           

          'container.addChild(childComponent);'.

           

           

           

           

          With Regards,

           

          Shardul Singh Bartwal

          • 2. Re: Using containers
            SiHoop Level 1

            I've tried to do what you recommend by adding a Canvas, but if I try to add the shape to the Canvas, I still get an error. I don't understand why I cannot add to the Canvas-- UIComponent is a DisplayObjectContainer as well as a/flash/display/DisplayObjectContainer.html Display object, but so is Canvas. For that matter, so is Application. Why can't I add 'shape' to the Canvas or Application using addChild?

             

            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
                <mx:Script>
                    <![CDATA[
            private var shape:Shapes
            public function init():void{
                shape=new Shapes()
                //this.addChild(shape);
                container1.addChild(shape);
                //rawChildren.addChild(shape);
            }
                    ]]>
                </mx:Script>
            <mx:UIComponent id="container" />
            <mx:Canvas id="container1" />
            </mx:Application>

            • 3. Re: Using containers
              ShardulSingh Level 3

              We can add directly as addChild to those container which implements 'mx.core.IUIComponent',both canvas and Application does not implements this so we have to add as rawchildren, while UIcomponent implements 'mx.core.IUIComponent',so we can directly add as addChild.

               

               

               

               

               

              with Regards,

               

              Shardul Singh Bartwal

              • 4. Re: Using containers
                SiHoop Level 1

                OK, that makes sense now. So if you want to add an instance to the stage, and the instance extends Sprite, are you generally going to add as a child to a UIComponent or use rawChildren, or is there some other approach that you would use?

                • 5. Re: Using containers
                  Flex harUI Adobe Employee

                  IMHO, it depends on what that Sprite is.  If it just a decoration and there is only one, I'd add it to rawChildren.  If there are many instance, it needs to participate in layout (save room for itself) or is interactive, I wouldn't extend Sprite, I would follow the custom component development rules and extend UIComponent.

                   

                  Alex Harui

                  Flex SDK Developer

                  Adobe Systems Inc.

                  Blog: http://blogs.adobe.com/aharui

                  • 6. Re: Using containers
                    SiHoop Level 1

                    It's taken about 2 1/2 years of using Flex, but I think I've just figured out something important! I think you are telling me the following:

                     

                    I should not extend Sprite. I should extend IUComponent because that will allow my instance to be displayed as a child of Application. By using extends I am making my class a subclass of IUComponent. Is this correct?

                    • 7. Re: Using containers
                      Flex harUI Adobe Employee

                      Yes.  The Flex Framework will do lots of cool things for you if you participate in the rules of component development, such as sizing, layout, scrolling, etc.  But, you have to participate.  Low-level Flash objects do not have the APIs we need to do these things automatically so we discourage use of them except as leaf objects in skins of a UIComponent-derived component.  That's why:

                       

                      Navigator children must be Containers

                      Container children must be IUIComponents

                      UIComponent children can be anything

                       

                      But UIComponent does not have any default behavior around measuring and layout so you have to override the lifecycle events (createChildren, commitProperties, measure, updateDisplayList).

                       

                      All of that cool stuff takes up code and memory which is why a Flex SWF is not as small as a custom Flash SWF.

                       

                      In Spark, there will be similar rules, but lighterweight containers are available so you can assemble lighterweight components with less code.

                       

                      Alex Harui

                      Flex SDK Developer

                      Adobe Systems Inc.

                      Blog: http://blogs.adobe.com/aharui

                      1 person found this helpful
                      • 8. Re: Using containers
                        SiHoop Level 1

                        Alex,

                        Thanks so much for your reply. Some of what you explained is over my head, but I think you are telling me not to use Sprites or MovieClips unless I have to-- is this what you mean?

                         

                        MY OOP skills are developing rapidly, but I don't understand the following comments that you made:

                        Navigator children must be Containers-- what are navigator children?

                        Container children must be IUIComponents--how do I figure out which of my objects are IUIComponents. Is it just a matter of reading the documentation?

                         

                        Can you recommend a good source to learn about the rules of component development and how to override lifecycle events?

                        • 9. Re: Using containers
                          Flex harUI Adobe Employee

                          Sprite, Shape and MovieClips can be used in skins, but generally should be avoided elsewhere.

                           

                          Accordion, Viewstack and TabNavigator are Navigators.

                           

                          Since most components extend UIComponent, they are IUIComponents.  The documentation will help you determine what isn't.

                           

                          The doc has a section on Custom Components.  Gordon and I wrote an article on it for Flex Authority magazine.  Various folks have blogged on it.

                           

                          Alex Harui

                          Flex SDK Developer

                          Adobe Systems Inc.

                          Blog: http://blogs.adobe.com/aharui

                          1 person found this helpful
                          • 10. Re: Using containers
                            SiHoop Level 1

                            Thank you!