18

私はJavaFX2.1を使用し、FXMLを使用してGUIを作成しました。このGUIのコントローラーに、を追加しましmyTextField.requestFocus();た。

しかし、私は常に他のコントロールに焦点を合わせています。

4

7 に答える 7

63

コントロールの時点でinitialize()は、まだフォーカスを処理する準備ができていません。

次のトリックを試すことができます:

@Override
public void initialize(URL url, ResourceBundle rb) {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            tf.requestFocus();
        }
    });
}

トリッキーで複雑なアプリケーション(Pavel_Kのコメントにあるような)の場合、このルーチンを数回繰り返して、次のメソッド行を呼び出すことができます。

private void requestFocusOrDieTrying(Node node) {
    Platform.runLater(() -> {
        if (!node.isFocused()) {
            node.requestFocus();
            requestFocusOrDieTrying(node);
        }
    });
}

これは文書化されていないアプローチであり、将来のJavaリリースで何かが変更または破損した場合に無限のループを回避するために、繰り返しの制限を追加するのが賢明であることに注意してください。アプリ全体よりもフォーカスを失う方が良いです。:)


説明されているしきい値の例:

@Override
public void requestFocus() {
  requestFocus( getNode(), 3 );
}

private void requestFocus( final Node node, final int max ) {
  if( max > 0 ) {
    runLater(
        () -> {
          if( !node.isFocused() ) {
            node.requestFocus();
            requestFocus( node, max - 1 );
          }
        }
    );
  }
}
于 2012-10-05T10:57:05.613 に答える
12

@Sergey Grinevとまったく同じ答え。Java のバージョンが最新であることを確認してください (JDK 1.8 以降)。

Platform.runLater(()->myTextField.requestFocus());
于 2016-08-11T15:24:04.693 に答える
4

これは、ノードの Scene プロパティがまだ設定されていない場合に発生する可能性があります。残念ながら、シーン プロパティの設定には「長い」時間がかかる場合があります。

子ノードのシーン プロパティは、シーンが最初に作成されたときと、アイテムが TabPane などの一部の親に追加されたときに遅延します (奇妙なことに一部の親は免疫があるように見えますが、理由はわかりません)。

常に私のために働いてきた正しい戦略:

if (myNode.scene) == null {
    // listen for the changes to the node's scene property,
    // and request focus when it is set
} else {
    myNode.requestFocus()
}

これを行う便利な Kotlin 拡張関数があります。

fun Node.requestFocusOnSceneAvailable() {
    if (scene == null) {
        val listener = object : ChangeListener<Scene> {
            override fun changed(observable: ObservableValue<out Scene>?, oldValue: Scene?, newValue: Scene?) {
                if (newValue != null) {
                    sceneProperty().removeListener(this)
                    requestFocus()
                }
            }
        }
        sceneProperty().addListener(listener)
    } else {
        requestFocus()
    }
}

次に、次のようにコード内から呼び出すことができます。

myNode.requestFocusOnSceneAvailable()

おそらく誰かがそれをJavaに翻訳したいと思うでしょう。

于 2018-09-17T17:48:38.727 に答える