3 Replies Latest reply on Aug 15, 2010 10:28 PM by MikisMM

    Null object reference when using BorderContainer

    tzejing

      Hi

       

      I have the following component (MyComp.mxml) and application (MyApp.mxml) :

       

      MyComp.mxml

      <?xml version="1.0" encoding="utf-8"?>
      <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
          <fx:Script>
              <![CDATA[
                  public function set label(s:String):void 
                  {
                      mybutton.label = s;
                  }
              ]]>
          </fx:Script>
          <!-- The BorderContainer will cause error -->
          <s:BorderContainer>
              <s:Button id="mybutton" />          
          </s:BorderContainer>
      </s:Group>
      
      

       

      MyApp.mxml

      <?xml version="1.0" encoding="utf-8"?>
      <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"
                     xmlns:local="*">
          <local:MyComp label="hello" />
      </s:Application>
      
      

       

       

      The MyApp will throw the following error because mybutton is null when the setter property function is called :

       

      TypeError: Error #1009: Cannot access a property or method of a null object reference.
           at MyComp/set label()[C:\Adobe Flash Builder 4\Test\src\MyComp.mxml:9]
           at MyApp/_MyApp_MyComp1_c()[C:\Adobe Flash Builder 4\Test\src\MyApp.mxml:5]
           at MyApp/_MyApp_Array1_c()
           at mx.core::DeferredInstanceFromFunction/getInstance()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\DeferredInstanceFromFunction.as:105]
           at spark.components::SkinnableContainer/createDeferredContent()[E:\dev\4.x\frameworks\projects\spark\src\spark\components\SkinnableContainer.as:985]
           at spark.components::SkinnableContainer/createContentIfNeeded()[E:\dev\4.x\frameworks\projects\spark\src\spark\components\SkinnableContainer.as:1014]
           at spark.components::SkinnableContainer/createChildren()[E:\dev\4.x\frameworks\projects\spark\src\spark\components\SkinnableContainer.as:827]
           at mx.core::UIComponent/initialize()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:7349]
           at spark.components::Application/initialize()[E:\dev\4.x\frameworks\projects\spark\src\spark\components\Application.as:916]
           at MyApp/initialize()
           at mx.managers.systemClasses::ChildManager/childAdded()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\systemClasses\ChildManager.as:189]
           at mx.managers.systemClasses::ChildManager/initializeTopLevelWindow()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\systemClasses\ChildManager.as:341]
           at mx.managers::SystemManager/initializeTopLevelWindow()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\SystemManager.as:2810]
           at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::kickOff()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\SystemManager.as:2637]
           at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::preloader_completeHandler()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\SystemManager.as:2539]
           at flash.events::EventDispatcher/dispatchEventFunction()
           at flash.events::EventDispatcher/dispatchEvent()
           at mx.preloaders::Preloader/timerHandler()[E:\dev\4.x\frameworks\projects\framework\src\mx\preloaders\Preloader.as:515]
           at flash.utils::Timer/_timerDispatch()
           at flash.utils::Timer/tick()
      
      

       

       

      Do you have any idea why the mybutton is not created when the label property is set?

       

      It seems that the BorderContainer is causing the problem. The error disappears when I use Group instead of BorderContainer.

       

       

      Thank you!

        • 1. Re: Null object reference when using BorderContainer
          Subeesh Arakkan Level 4

          Hi,

           

          The button instance is causing the error as it is not initialized when the value is set. You need to wait till the button is completely initialized. The best approach as far I know is to override the commitProperties() method. Here is the modified component code.

           

          <?xml version="1.0" encoding="utf-8"?>
          <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
               <fx:Script>
                    <![CDATA[
                         
                         private var _label:String;
                         private var _labelChanged:Boolean;
                         public function set label(s:String):void 
                         {
                              _label = s;
                              _labelChanged = true;
                              invalidateProperties();
                         }
                         
                         override protected function commitProperties():void
                         {
                              super.commitProperties();
                              if(_labelChanged)
                              {
                                   _labelChanged = false;
                                   mybutton.label = _label;
                              }
                         }
                    ]]>
               </fx:Script>
               
               <s:BorderContainer>
                    <s:Button id="mybutton" />          
               </s:BorderContainer>
          </s:Group>
          

          • 2. Re: Null object reference when using BorderContainer
            tzejing Level 1

            Hi Subeesh

             

            Do you know why there is no problem when I use Group instead of the BorderContainer? Is there any different in the initialization between Group and BorderContainer?

            • 3. Re: Null object reference when using BorderContainer
              MikisMM Level 2

              Yes. There is. BorderContainer extends from SkinnableContainer which has this "deffered children creation" (or whatever it's called) feature: children of the container are created only when skin is attached to the component which happens after your property is set.

              Anyway, when creating components you should (in most cases) take into account component lifecycle and implement your components accordingly. Read this document if you need more information about that.