0

我正在将 Flex 3.0 应用程序升级到 Flex 3.6 SDK。该应用程序具有用于输入文本、组合框等的自定义控件。当我单击组合框时,调用 super.commitProperties() 时出现异常。这适用于 Flex 3.0 SDK。

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at mx.controls::ComboBox/destroyDropdown()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1681]
    at mx.controls::ComboBox/styleChanged()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1177]
    at mx.core::UIComponent/setBorderColorForErrorString()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:5048]
    at mx.core::UIComponent/commitProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:6033]
    at mx.controls::ComboBase/commitProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBase.as:993]
    at mx.controls::ComboBox/commitProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1291]
    at com.hanover.utility.controls.autotestcontrols::AutotestComboBox/commitProperties()[C:\App\Control\PLCustomComboBox.as:59]
    at mx.core::UIComponent/validateProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:5966]
    at mx.managers::LayoutManager/validateProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:539]
    at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:689]
    at mx.managers::LayoutManager/validateNow()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:748]
    at mx.controls::ComboBox/displayDropdown()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1638]
    at mx.controls::ComboBox/downArrowButton_buttonDownHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1796]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9590]
    at mx.controls::Button/http://www.adobe.com/2006/flex/mx/internal::buttonPressed()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\Button.as:2504]
    at mx.controls::Button/mouseDownHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\Button.as:2750]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9590]
    at mx.controls::ComboBase/textInput_mouseEventHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBase.as:1384]

PLCustomCombobox.as 伪源代码,第 59 行如下所示

package com
{
    import com.name.utility.events.PLControlEvent;
    import com.name.utility.managers.ComboToolTipManager;

    import flash.events.Event;

    import mx.controls.ComboBox;
    import mx.events.FlexEvent;

    [Event(name="controlInitComplete", type="com.events.PLControlEvent")]

    [Event(name="plusControlValueChanged", type="com.name.utility.events.PLControlEvent")]

    public class PLControlComboBox extends ComboBox 
                                implements IPLControlControl
    {
        /**
         * A flag that indicates whether the control need to refresh.
         */     
        protected var isNeedRefresh:Boolean = false;

        /**
         * A flag that indicates whether the value of control is changed.
         */     
        protected var isValueChanged:Boolean = false;

        /**
         *  Constructor.
         */
        public function PLControlComboBox()
        {
            super();
            this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
        }

        /**
         * @private
         * override commitProperties for avoid dispatch event many times.
         */     
        override protected function commitProperties():void
        {
            super.commitProperties(); // <---- line # 59 is here

            if(isNeedRefresh)
            {
                this.dispatchEvent(new PLControlEvent(PLControlEvent.VALUE_CHANGED));
                isNeedRefresh = false;
            }

            if(isValueChanged)
            {
                this.dispatchEvent(new Event("PLControlComboboxChanged"));
                isValueChanged = false;
            }
        }

        /**
         * Add item's tooltip.
         * @private
         */
        override public function set measuredWidth(value:Number):void
        {
            super.measuredWidth = value;
            if(collection && collection.length > 0)
            {
                ComboToolTipManager.showItemToolTip(this);
            }
        }
        protected function onCreationComplete(event:FlexEvent):void
        {
            this.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
            this.dispatchEvent(new PLControlEvent(PLControlEvent.INIT_COMPLETE));
        }

        public function checkValidity():void
        {
            if(_required && dataProvider && dataProvider.length > 0 && _defaultItemIndex == selectedIndex)
            {
                _validity   = false;
                errorString = "please select one";
            }
            else
            {
                _validity   = true;
                errorString = "";
            }
        }

        // ======================================
        // public function
        // ======================================
        private function itemChanged():void
        {
            isNeedRefresh = true;
            isValueChanged = true;
            checkValidity();
        }

        // ======================================
        // properties
        // ======================================

        private var _required:Boolean       = false;
        private var _validity:Boolean       = false;
        private var _defaultItemIndex:int   = 0;

        public function get required():Boolean
        {
            return _required;
        }

        [Inspectable(defaultValue=false, category="Other")]
        public function set required(value:Boolean):void
        {
            _required       = value;
            isNeedRefresh   = true;
            checkValidity();
        }

        [Bindable("PLControlComboboxChanged")]
        public function get controlValue():Object
        {
            return this.selectedIndex;
        }

        public function set controlValue(value:Object):void
        {
            if(value is Number)
            {
                this.selectedIndex = int(value);
                itemChanged();
            }
        }

        /**
         * @copy IPLControlControl#validity
         */
        public function get validity():Boolean
        {
            return _validity;
        }

        /**
         * @copy IPLControlControl#type
         */
        public function get type():String
        {
            return PLControlTypeList.CONTROL_TYPE_COMBOBOX;
        }

        /**
         * If required is true, the default Item can not be selected.
         */
        public function get defaultItemIndex():int
        {
            return _defaultItemIndex;
        }

        [Inspectable(defaultValue=0, type="Number", category="Other")]
        public function set defaultItemIndex(index:int):void
        {
            _defaultItemIndex = index;
            isNeedRefresh   = true;
            checkValidity();
        }

        /**
         * Override for check validity.
         */
        override public function set selectedIndex(value:int):void
        {
            super.selectedIndex = value;
            itemChanged();
        }

        /**
         * Override for check validity.
         */
        override public function set selectedItem(value:Object):void
        {
            super.selectedItem = value;
            itemChanged();
        }
    }
}

它来自 mx.controls.Comboxbox 第 1681 行,因为补间为空。

private function destroyDropdown():void
    {
        if (inTween)
            tween.endTween();//<---- exception on this line

        displayDropdown(false, null, false);
    }

关于为什么会发生这种情况的任何建议?

4

1 回答 1

1

Apache Flex 4.10 及更高版本中已修复的问题,请参阅https://issues.apache.org/jira/browse/FLEX-33382

如果使用较旧的 SDK,您可以修改 mx:ComboBox 像这样添加“&& tween”检查:

private function destroyDropdown():void
{
    if (inTween && tween)
        tween.endTween();

    displayDropdown(false, null, false);
}
于 2013-02-05T02:03:02.910 回答