5 Replies Latest reply on May 7, 2009 2:33 PM by crissy84

    Where to begin with 'composite component'?

    crissy84 Level 1

      Hi everyone.  I'm having a hard time understanding how to build a basic composite component.  There is some online documentation on this, but for some reason, I just cannot follow it.  Honestly, I'm not trying to get someone here to do my work for me, but I'm hoping that if described a very simplified version of what I need to do, that someone could show me how to do it through code.

       

      Here's what I'm essentially trying to do (build a control that is a combobox with a button on the side of it):

       

      <hbox>

           <combobox/>

           <button/>

      </hbox>

       

       

      Doing something like above is easy enough.  But what I really need is for the root control to be a combobox so that all properties and events of the combobox are available to its owner without me having to re-implment/proxy all of them.

      Hopefully this will illustrate the concept:

       

      <combobox>

           <button/>

      </combobox>

       

      I see from the doc that I need an AS class and have to override updateDisplayList, createChildren, etc.  But for some reason, I just cannot understand the doc enough to do something even this simple.  I think if someone showed me how to do this example, then it would be a good starting point for me to go back to the doc and hopefully it'll make more sense!

       

      Thanks in advance!

        • 1. Re: Where to begin with 'composite component'?
          Michael Borbor Level 4

          I don't know if I fully understand what you need, but in any case you just

          need to add an id, to your components children the app that will include

          those components will be able to access them. If this isn't what you mean,

          sorry.

          • 2. Re: Where to begin with 'composite component'?
            John Hall Level 4

            I agree with Michael that it's a bit tough to figure out where you're going. It sounds like you're wanting to create an ActionScript component, which is fine, but just want to make sure you understand that you can also create components in MXML, which comes in handy sometimes.

             

            For instance, if you had a simple main application:

             

            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns="*">
                <MyComponent x="114" y="56" />
            </mx:Application>

             

            it could be based on another file, an MXML component called MyComponent.mxml in the same folder that is based on your hbox (or whatever).

             

             

            <?xml version="1.0" encoding="utf-8"?>
            <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="238" height="26">
                <mx:Script>
                    <![CDATA[
                        import mx.controls.Alert;
                        private var myHealth:String = "Alive";
                    ]]>
                </mx:Script>
                <mx:Button label="Button" click="Alert.show(myHealth.toString())"/>
                <mx:ComboBox></mx:ComboBox>
            </mx:HBox>

            • 3. Re: Where to begin with 'composite component'?
              Gregory Lafrance Level 6

              To chime in here, it sounds like what you want is a component as you have described it, HBox as root tag, with ComboBox and Button as children. Give the ComboBox and Button an id and you can access them using an instance of your component:

               

              var mycomp:MyComponent = new MyComponent();

              mycomp.myCB.dataProvider = myArrayCollection;

              mycomp.myBtn.label = "Click Me";

              • 4. Re: Where to begin with 'composite component'?
                ntsiii Level 3

                I think the o.p is loking for an example of composition that starts by extending some component like ComboBox, and then adds another control to it.  the benefit of this is that the new control can be treated as  a ComboBox, with all of its functionality.  Here is an example.  You will need to find your own image to use for the button, or change it to a regular button.

                 

                ComboButton.jpg

                 

                Test application:

                <?xml version="1.0" encoding="utf-8"?>
                <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                    xmlns="*"
                    layout="absolute"
                    creationComplete="init()" >
                   
                <mx:Script><![CDATA[
                  import mx.collections.ArrayCollection;
                  import mx.controls.Alert;

                  [Bindable]private var _acDP:ArrayCollection;
                 
                  public function init():void
                  {
                    _acDP = new ArrayCollection([{label:"one", value:1},{label:"two", value:2},{label:"three", value:3}])
                  } 
                  private function onButtonClick(event:Event):void
                  {
                    Alert.show(ComboButton(event.currentTarget).selectedLabel);
                  }
                ]]></mx:Script>    
                <ComboButton dataProvider="{_acDP}" labelField="label" comboButtonClick="onButtonClick(event)" />
                </mx:Application>

                 

                ComboButton.as

                package
                {
                  import flash.events.Event;
                  import flash.events.MouseEvent;
                  import mx.controls.ComboBox;
                  import mx.controls.Image;
                 
                  [Event(name="comboButtonClick", type="flash.events.Event")]
                  public class ComboButton extends ComboBox
                  {
                    [Embed(source="assets/help.gif")]
                    private var buttonImage:Class;
                   
                    private var _imgButton:Image;

                 

                    //Constructor
                    public function ComboButton()
                    {
                     super();
                    }
                   
                    /** instantiates the button and adds it to the displaylist */
                    override protected function createChildren():void
                    {
                      super.createChildren();                // Call to the superclass for necessary processing.
                      if(!_imgButton) {                       // Create the button component.
                        _imgButton = new Image();
                        _imgButton.source = buttonImage;
                        _imgButton.toolTip = "Click Me";
                        _imgButton.addEventListener(MouseEvent.CLICK, onClickButton);
                        addChild(_imgButton);
                      }   
                    }//
                   
                    /** Positions and sizes the image button */
                    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
                    {
                      super.updateDisplayList(unscaledWidth, unscaledHeight);
                        var buttonHeight:Number =  unscaledHeight;
                        var buttonWidth:Number = buttonHeight; 
                        var nbuttonX:Number = unscaledWidth + 5;
                        var nbuttonY:Number = 0;
                        _imgButton.height = buttonHeight;
                        _imgButton.width = buttonWidth;
                        _imgButton.move(nbuttonX, nbuttonY);
                    }//updateDisplayList 
                   
                    /** dispatches event on button click */
                    private function onClickButton(event:MouseEvent):void
                    {
                      dispatchEvent( new Event("comboButtonClick", false));
                    }    
                  }//public class ComboButton
                }//package

                 

                Tracy Spratt

                • 5. Re: Where to begin with 'composite component'?
                  crissy84 Level 1

                  Thanks everybody for your suggestions.  Tracy, you hit the nail on the head.  Sorry it took me so long to reply, but I was looking for the documentation that I found before that describes this better than me.  I couldn't find the doc!

                  Sorry if I wasn't clear in my original, but like Tracy said, I need the Combobox to be the root component.  So that it is essentially just an extended combobox instead of a combobox bundled with some other components.  On the surface they seem the same, but there is a difference.

                  Tracy, I'm going to inspect your code now and hopefully it'll finally click for me

                  Oh, and thanks again for the code!!!!