1

Visual Basic 6 では、フォーム ボタン コントロールの DefaultButton プロパティを true に設定すると、フォーム内の他のすべてのボタン コントロールの同じプロパティが false に設定されました。つまり、プロパティは (ラジオ ボタンのように) 相互に排他的でした。

JavaFX の複数のボタンで defaultButton プロパティが true に設定されている可能性があり、複数のボタンがシステムから VK_Enter ボタン イベントを受け取ることを示すように見える GUI の動作が発生しています。

setDefaultButton() メソッドと defaultButton プロパティに関する JavaFX 2.2 のドキュメントでは、この問題が明確にされていません。

コントロールの束を持つ 1 つの AnchorPanel と、別のコントロールの束を持つ別の AnchorPanel があります。これらは同じステージに表示され、どれが setVisible(true) であるかは、操作している情報によって異なります。

Enter を受け取る複数のボタンに起因する奇妙な動作を避けるために、1 つを true に設定しようとする前に、アクティブなペインのボタン コントロールを反復処理し、それらすべてに対して defaultButton プロパティを false に設定する必要があるかどうか疑問に思っています。重要な出来事。

EDIT 05/05/2013 -- これが私が持っている ChangeListener コードです。私は元々、TextField コントロール txtDx の focusdProperty に直接アタッチする匿名の内部クラスとして記述していました。ただし、リスナーを起動させたくないとき (つまり、ペインが非表示または無効になっているとき) にリスナーを削除することで、エラーを修正できるのではないかと考えました。そこで、Listener を内部クラスに移動し、そのインスタンスをインスタンス変数によって参照するようにしました。参照があると、表示されているペインに応じてリスナーを追加および削除できます。

とにかく、ここにリスナークラスがあります:

private class FocusPropertyChangeListener implements ChangeListener<Boolean> {

    FocusPropertyChangeListener() { System.out.println("New FPCL instance"); }

    @Override
    public void changed(ObservableValue<? extends Boolean> ov, 
        Boolean oldb, Boolean newb) {
        System.out.println("Focus change triggered");

        if (ancEncEditor.isVisible() && !ancEncEditor.isDisabled()) {
            boolean b = (newb != null && newb.booleanValue() == true);
            System.out.println("txtDx focus change event triggered: DxAdd = " + b);

            btnWindowCommit.setDefaultButton(!b);
            btnWindowClose.setCancelButton(true);
            btnDxAdd.setDefaultButton(b);
        }
    }
}

ご覧のとおり、イベント ハンドラーで、setDefaultButton に対して 2 つの (おそらく同時の) 呼び出しを行います。txtDx で編集している場合は btnDxAdd を使用し、それ以外の場合は btnWindowCommit を使用します。おそらく不必要な setDefaultButton への呼び出しを取り除き、まだ ConcurrentModificationExceptions が発生するかどうかを確認します。

EDIT 05/05/2013 -- スタック トレースを追加します。ここに行きます...

java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)
at java.util.HashMap$EntryIterator.next(HashMap.java:934)
at java.util.HashMap$EntryIterator.next(HashMap.java:932)
at com.sun.javafx.collections.ObservableMapWrapper$ObservableEntrySet$1.next(ObservableMapWrapper.java:560)
at com.sun.javafx.collections.ObservableMapWrapper$ObservableEntrySet$1.next(ObservableMapWrapper.java:548)
at com.sun.javafx.scene.KeyboardShortcutsHandler.processAccelerators(KeyboardShortcutsHandler.java:286)
at com.sun.javafx.scene.KeyboardShortcutsHandler.dispatchBubblingEvent(KeyboardShortcutsHandler.java:119)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$KeyHandler.process(Scene.java:3513)
at javafx.scene.Scene$KeyHandler.access$2300(Scene.java:3472)
at javafx.scene.Scene.impl_processKeyEvent(Scene.java:1904)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2270)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:136)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:100)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:163)
at com.sun.glass.ui.View.handleKeyEvent(View.java:518)
at com.sun.glass.ui.View.notifyKey(View.java:951)
at com.sun.glass.ui.win.WinApplication._enterNestedEventLoop(Native Method)
at com.sun.glass.ui.Application.enterNestedEventLoop(Application.java:383)
at com.sun.glass.ui.EventLoop.enter(EventLoop.java:83)
at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:520)
at javafx.stage.Stage.showAndWait(Stage.java:397)
at org.kls.md.censusassistant.DialogController.showAndWait(DialogController.java:94)
at org.kls.md.censusassistant.DCMainEditor.handleEncDetails(DCMainEditor.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:279)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1435)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Node.fireEvent(Node.java:6863)
at javafx.scene.control.Button.fire(Button.java:179)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:193)
at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:336)
at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:329)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:64)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3328)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3168)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3123)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1563)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2265)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:250)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:173)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:292)
at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
at com.sun.glass.ui.View.notifyMouse(View.java:922)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)

EDIT 05/05/2013 -- コードを変更して、defaultButton の以前の設定をクリアしないようにしました。つまり、setDefaultButton(true) を 1 回呼び出すだけです。バッキング コードが Runnable を使用してこの操作を実行するため、おそらくこれが、取得していた ConcurrentModificationExceptions の原因であるという考えでした。

そのため、実際には、デフォルト ボタンとして btnDxAdd と btnWindowCommit の間で変更しようとすると、コードで ConcurrentModificationExceptions をトリガーできなくなったようです。

でも ...

また、私が望む動作を得ることができなくなりました。現在、txtDx コントロールで編集しているときに、1 日中 Enter キーを押してもボタンが起動しません。focusProperty ChangeListener が起動し、txtDx.setDefaultButton(true) への単一の呼び出しが行われたことを確認しました。とにかく、私は私が望む行動を得ることができません。

4

1 に答える 1