views:

499

answers:

1

Hi Guys!

Here is the error:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
        at mx.styles::StyleProtoChain$/initProtoChainForUIComponentStyleName()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\styles\StyleProtoChain.as:72]
        at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::initProtoChain()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:7469]
        at mx.core::UIComponent/regenerateStyleCache()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:7690]
        at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::addingChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5239]
        at mx.core::UIComponent/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:4955]
        at mx.controls.listClasses::ListBase/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3103]
        at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
        at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5267]
        at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3305]
        at mx.core::Container/addChildAt()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2217]
        at mx.core::Container/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2140]
        at model::MessageBoard()[C:\Documents and Settings\dbabbitt\My Documents\Flex Builder 3\ListExample\src\model\MessageBoard.as:56]
        at model::MessageBoard$cinit()
        at global$init()[C:\Documents and Settings\dbabbitt\My Documents\Flex Builder 3\ListExample\src\model\MessageBoard.as:7]
        at main()[C:\Documents and Settings\dbabbitt\My Documents\Flex Builder 3\ListExample\src\main.mxml:56]
        at _main_mx_managers_SystemManager/create()
        at mx.managers::SystemManager/initializeTopLevelWindow()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3188]
        at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3064]
        at mx.managers::SystemManager/docFrameListener()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2916]

Here is main.mxml:

    <?xml version="1.0"?>
    <mx:Application
        xmlns:mx="http://www.adobe.com/2006/mxml"
    >
        <mx:Script>
            <![CDATA[
                import model.MessageBoard;
                public var _messageBoard:MessageBoard = MessageBoard.instance;
            ]]>
        </mx:Script>
    </mx:Application>
Here is MessageBoard.as:

package model {
    import mx.containers.VBox;
    import mx.controls.Label;

    [Bindable]
    public class MessageBoard extends VBox {

        /** The message list title. */
        private var _messageTitle:Label;

        /** The maximum message count. */
        private var _maxMessageCount:int = 4;

        /** Storage for the singleton instance. */
        private static const _instance:MessageBoard = new MessageBoard( SingletonLock );

        /** Provides singleton access to the instance. */
        public static function get instance():MessageBoard {
            return _instance;
        }

        /**
         * Constructor
         * 
         * @param lock The Singleton lock class to pevent outside instantiation.
         */
        public function MessageBoard( lock:Class ) {
            super();

            // Verify that the lock is the correct class reference.
            if ( lock != SingletonLock ) {
                throw new Error( "Invalid Singleton access.  Use MessageBoard.instance." );
            }

            _messageTitle = new Label();
            _messageTitle.text = "Message Board";
            this.addChild(_messageTitle);
        }

    } // end class
} // end package

class SingletonLock {
} // end class

Maybe you could school me in how to keep null object references out of complex Classes?

Thanx

Dave

+1  A: 

It looks like the error may be coming from the call to the addChild() method in the constructor of your MessageBoard class. You may very well be invoking this method too early in the UIComponent lifecycle. I would recommend overriding the createChildren() method and adding your child element(s) there.

override protected function createChildren():void
{
    super.createChildren();
    _messageTitle = new Label();
    _messageTitle.text = "Message Board";
    this.addChildAt(_messageTitle, 0);
}
cliff.meyers
Could you demonstrate what you are talking about?
Dave Babbitt
Code sample added.
cliff.meyers
I think I understand how to create composite objects now, thanks to your gentle nudge: the "this.addChild" sections must be pushed into the createChildren method. If you have other .addChild sections, they must go into their own classes where the process is repeated.
Dave Babbitt
For the most part that's correct. Sometimes you need to create children as the result of a property being set on a custom component. In that case, write a setter for the property and call invalidateProperties() inside it; this will cause commitProperties() to be called later on. You can then override commitProperties() and create or destroy the children as needed dynamically. This is the same mechanism that a lot of built-in Flex components use and it's incredibly useful to understand how it all works. :)
cliff.meyers