11 Replies Latest reply on Jun 14, 2010 12:47 PM by lkenney2

    Enable all Objects of a Class

    lkenney2 Level 1

      I'm trying to set up a a program where all instances of an extended Button class can be enabled or disabled at once.

       

      In other words, I have a class, TestButton.as, and in my Main class I'd like to be able to write TestButton.enabled = true for all instances of that class.

       

      I've being googling, but haven't managed to find the answer. Please help?

        • 1. Re: Enable all Objects of a Class
          msakrejda Level 4

          If you can control instantitation, you could create a buttonFactory, and when you create a button register the instance with something like a TestButtonManager class. Then use the TestButtonManager to control enabled / disabled state. If you can't control instantiation, you could add code to the TestButton constructor to register itself through some pre-defined static referenced (e.g., TestButtonManager.instance), although that's definitely a fishier solution (since it couples it to the manager). Alternately, you could bind the TestButton's enabled property to a static member variable on the TestButton class, but that's also kinda smelly...

          • 3. Re: Enable all Objects of a Class
            lkenney2 Level 1

            Hey msakrejda, thanks for the fast resonse. The first way you described is really unfamiliar sounding - would it be possible for you to go into some more details?

             

            Thanks.

            • 4. Re: Enable all Objects of a Class
              Gregor.Kiddie

              You could walk all the children on the display list, and test the type.

               

              Something like

               

              public function enableButtons( component : DisplayObjectContainer ) : void {

                  for ( var i : int = 0; i < component.numChildren; i++ ) {

                      if ( component.getChildAt( i )  is DisplayObjectContainer ) {

                          enableButtons( component.getChildAt( i ) );

                      } else if ( component.getChildAt( i )  is TestButton ) {

                          component.enable = true;

                      }

                  }

              }

               

              Not exactly the most performant way of doing it, but it should work!

              • 5. Re: Enable all Objects of a Class
                msakrejda Level 4

                class TestButtonManager() {

                    private var _buttons:Dictionary = new Dictionary(true);

                    public function addButton(btn:TestButton):void {

                      _buttons[btn] = true;

                    }

                    public function toggleAll(enabled:Boolean):void {

                      for (var btn:Object /* note: can't declare this as TestButton due to mxmlc limitation*/ in _buttons) {

                        btn.enabled = enabled;

                      }

                    }

                }

                 

                class TestButtonFactory {

                    public static var manager:TestButtonManager = new TestButtonManager();

                    public static function createButton():TestButton {

                      var btn:TestButton = new TestButton();

                      manager.addButton(btn);

                      return btn;

                    }

                }

                 

                Something along those lines (this is quick and dirty, but this is the concept I was thinking of). Then instead of calling new TestButton(), just call TestButtonFactory.createButton(). If you're declaring your TestButtons in mxml, though, you can't do something like this (at least not today; I imagine support could be added for mxml component factories at some point).

                1 person found this helpful
                • 6. Re: Enable all Objects of a Class
                  jsd99 Level 3

                  I use a class I created called NotificationCenter for this purpose.  It's a very small class:

                   

                   

                  package com.jsd {

                       import flash.events.IEventDispatcher;

                       import flash.events.EventDispatcher;

                   

                       public class NotificationCenter extends EventDispatcher {

                            private static var _dc:NotificationCenter = new NotificationCenter();

                   

                            public function NotificationCenter(target:IEventDispatcher=null) {

                                 super(target);

                            }

                   

                            public static function get defaultCenter():NotificationCenter {

                                 return _dc;

                            }

                       }

                  }

                   

                   

                  So everytime you create one of your TestButtons, you would do:

                   

                  NotificationCenter.defaultCenter.addEventListener(TestButton.ENABLE_ALL, enableMyself);

                  NotificationCenter.defaultCenter.addEventListener(TestButton.DISABLE_ALL, disableMyself);

                  You obviously have to provide the enableMyself/disableMyself methods, and the ENABLE_ALL/DISABLE_ALL static strings for TestButton.

                  Then later on when you want to enable them all, you can do this from anywhere else in your application:

                  NotificationCenter.defaultCenter.dispatchEvent(new Event(TestButton.ENABLE_ALL));

                  • 7. Re: Enable all Objects of a Class
                    Shongrunden Adobe Employee

                    If you prefer to work in MXML you could take advantage of data binding and do something like this:

                     

                    CustomButton.mxml:

                    <s:Button xmlns:fx="http://ns.adobe.com/mxml/2009"
                              xmlns:s="library://ns.adobe.com/flex/spark"
                              enabled="{CustomButton.allButtonsEnabled}">
                        <fx:Script>
                            <![CDATA[
                                [Bindable] public static var allButtonsEnabled:Boolean = true;
                            ]]>
                        </fx:Script>
                    </s:Button>

                     

                    Then to disable all CustomButtons you would set CustomButton.allButtonsEnabled = false

                    • 8. Re: Enable all Objects of a Class
                      GordonSmith Level 4

                      Can't you just do something simple like this?

                       

                      class MyButton

                      {

                          static var instances:Array = [];

                       

                          public function MyButton()

                          {

                              super();

                              instances.push(this);

                          }

                       

                          public static function set enabled(value:Boolean):void

                          {

                              var n:int = instances.length;

                              for (var i:int = 0; i < n; i++)

                              {

                                  instances[i].enabled = value;

                              }

                          }

                      }

                       

                      Gordon Smith

                      Adobe Flex SDK Team

                      • 9. Re: Enable all Objects of a Class
                        msakrejda Level 4

                        Well, I think that definitely strips all my overengineering out of it. The only thing I'd change is to make instances a weak-key Dictionary instead of an Array, or you'll leak button instances once they're removed from the display list.

                        • 10. Re: Enable all Objects of a Class
                          GordonSmith Level 4

                          Good point!

                           

                          Gordon Smith

                          Adobe Flex SDK Team

                          • 11. Re: Enable all Objects of a Class
                            lkenney2 Level 1

                            Hi jsd. In the end, this wasn't quite what I did, but it was very clode, so I'd like to thank you for helping me out. I ended up using an extended event class with the ability to carry a variable, and an extended eventdispatch class with my dispatch functions. I.e. see below:

                             

                            public function enableAbortButton(isTrue:Boolean):void {
                                        dispatchEvent(new EduSpeakEvent(EduSpeakEvent.ENABLE_ABORT_BUTTON, {data:isTrue}));
                                    }

                             

                            In the button class I wanted to enable, I created an instance of the extended event dispatcher and added an event listener:

                             

                            public function EduSpeakAbortButton()
                                    {
                                        label = "Abort";
                                       
                                        displayLoader = new EduSpeakEventDispatch();
                                        displayLoader.addEventListener(EduSpeakEvent.ENABLE_ABORT_BUTTON, enableAbortButton);
                                    }
                                   
                                    private function enableAbortButton(e:EduSpeakEvent):void
                                    {
                                        this.enabled = e.param.data;
                                    }

                             

                             

                            And whenever I wanted to enable or disable the buttons, I created an instance of the event dispatcher and used the associated method:

                             

                            displayLoader.enableAbortButton(true);

                             

                            This seems to be working. So thanks, I couldn't have figured it out without you!