0

Scroller.asクラスの2139行目で、次のエラーが発生します。

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at spark.components::Scroller/focusInHandler()[E:\dev\4.y\frameworks\projects\spark\src\spark\components\Scroller.as:2139]
    at flash.display::Stage/set focus()

Scroller.asから

/**
 *  @private 
 *  Listens for any focusIn events from descendants 
 */ 
override protected function focusInHandler(event:FocusEvent):void
{
    super.focusInHandler(event);

    // When we gain focus, make sure the focused element is visible
    if (viewport && ensureElementIsVisibleForSoftKeyboard)
    {
        var elt:IVisualElement = focusManager.getFocus() as IVisualElement; 
        lastFocusedElement = elt;
    }
}

これはフレームワークコードなので、それを防ぐためにどのようなオプションが必要ですか?

コンテキスト
ポップアップTitleWindowを作成し、それにモジュールを追加して表示しました。モジュールにはいくつかの状態があり、各状態にはグループがあり、1つのグループにはリストがあり、そのリストにはItemRendererがあり、ItemRendererにはチェックボックスがあります。

モジュールにはメニューもあります。メニューを開くと、メニューポップアップにモジュールが使用可能な状態が一覧表示されます。メニューポップアップから項目を選択すると、別の状態に変わります。

状態が変更され、最後の項目がチェックボックスの場合、エラーが生成されます。少なくともそれが起こっていると私は思います。Scrollerクラスでは、ハンドラーがイベントを処理しているため、これを推測しました。そのイベントで現在のターゲットです。その現在のターゲットはチェックボックスです。

更新-再現する手順

// inside the Application.mxml
// define variables
public var popup:Group;
public var titleWindow:TitleWindow;


// shows pop up
public function showInspector():void {

    // inside show inspector method
    // create new inspector container
    popup = new InspectorContainer(); // a group implements="mx.managers.IFocusManagerContainer"
    titleWindow = new TitleWindow();
    titleWindow.addElement(popup);

    // display pop up title window
    PopUpManager.addPopUp(titleWindow, this, false);
}

<fx:Declarations>
    <modules:InspectorContainer/>
</fx:Declarations>
  1. ポップアップを表示します。ポップアップは、最初の要素としてInspectorContainer(グループ)を含むタイトルウィンドウです。

  2. ポップアップで、ホーム状態(デフォルト状態)からオンライン状態に変更します(これは、ユーザーがボタンをクリックしたときに発生します)。オンライン状態にはリストがあります。リストにはアイテムレンダラーがあります。itemrendererにはチェックボックスがあります。チェックボックスを選択します。ここまでは順調ですね。

  3. ポップアップ(InspectorContainer)にはmx:MenuBarインスタンスがあります。メニューバーの項目をクリックすると、メニューバーにメニュー項目が表示されます。

  4. メニューリストの項目をクリックします。itemClickmenuHandlerが呼び出されます。この関数では、ポップアップの状態が変わります。

これは、エラーが発生したときです。

4

3 に答える 3

4

エラーの主な理由は、UIComponentのget関数「focusManager」です。

public function get focusManager():IFocusManager
{
    if (_focusManager)
        return _focusManager;

    var o:DisplayObject = parent;

    while (o)
    {
        if (o is IFocusManagerContainer)
            return IFocusManagerContainer(o).focusManager;

        o = o.parent;
    }

    return null;
}

以下のコードのように、uicomponentがその親、parent.parent、parent.parent.parent ...からトラバースすることで、初めてフォーカスマネージャーを取得することがわかりますが、残念ながら、uicomponentがPopUpManager.addPopUp(popUp、this、 false); 親はSystemManagerであり、parent.parentはStageであり、どちらもIFocusManagerContainerではないため、focusManagerプロパティを持たないため、結果はnullになります。

最後に、私のソリューションは直接使用コンポーネントをオーバーライドし、2層コンポーネントを修正する必要がある場合は、focusManagerをそのコンポーネントに渡します。

package cn.easymenu.view.components{
 import mx.core.FlexGlobals;
 import mx.managers.IFocusManager;

 import spark.components.TextArea;

 public class TextArea extends spark.components.TextArea{
  override protected function partAdded(partName:String, instance:Object):void{
   super.partAdded(partName, instance);
   if(instance == scroller){
    scroller.focusManager=this.focusManager;
   }
 }

 override public function get focusManager():IFocusManager{
  var ifm:IFocusManager=super.focusManager;
  if(!ifm){
   ifm = FlexGlobals.topLevelApplication.focusManager;
  }
  return ifm;
  }
 }
}
于 2013-08-13T02:31:44.280 に答える
1

完全なコードは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" 
            autoDrawBackground="true"
            width="100%"
            implements="mx.managers.IFocusManagerContainer">

    <fx:Script>
    <![CDATA[
        public function get defaultButton():IFlexDisplayObject {
            return null;
        }

        public function set defaultButton(value:IFlexDisplayObject):void {
            // do nothing
        }

        override public function get systemManager():ISystemManager {
            return null;
        }
    ]]>
    </fx:Script>

    <!-- other stuff -->

    <s:CheckBox id="enabledCheckbox" />

</s:ItemRenderer>

解決策は、IFocusManagerContainerまたは基本的に必要な関数を実装することでした。私の場合、Scroller focusInHandlerハンドラーのfocusイベントのターゲットオブジェクト(コンポーネント)のコンテナーでsystemManagerゲッターをオーバーライドする必要がありました。

私はそれをこのように理解しました。ScrollerfocusInHandlerでエラーが発生します。フォーカスイベントのターゲットプロパティ(event.target)は、チェックボックス(フォーカスを持つ最後のアイテム)です。チェックボックスのコンテナは私のItemRendererです。ここで、IFocusManagerContainerインターフェイスを実装しました。このパスに沿って5つ以上の親レベルがあるため、これについて言及します。

ItemRendererに追加しました:

override public function get systemManager():ISystemManager {
    return null;
}

このメソッドは、mx.managers.IFocusManagerContainerインターフェースを実装するときに実装する必要のあるメソッドです。

そのインターフェースでは、defaultButtonのゲッターとセッターを定義する必要もありましたが、このエラーを解決する必要はありませんでした。テストでは、インターフェイスを削除し、defaultButtonメンバーを削除して、systemManagerゲッターを残しましたが、それでも問題は解決しました。

また、助けてくれたnoobsarepeople2に感謝します。

于 2012-08-05T02:16:28.340 に答える
1

を使用しているときにこの問題が発生しPopUpManagerました。

  1. これがAdobeのバグレポートです。
  2. これについての別のSO投稿があります。
  3. これは、関連している場合と関連していない場合がある別の投稿です(この問題の原因については言及していません)。

私の場合、最初と2番目のリンクの例に従い、そのサブクラスを作成Scrollerして、適切な場所でnullチェックを実行しました。これは私の特定の状況では問題なく、結果としてアプリに悪影響はありませんでした。そうは言っても、この「修正」はいつも私にとって少しハッキーだと感じていました。

于 2012-07-17T05:26:13.867 に答える