web-dev-qa-db-ja.com

TextFieldのRequestFocusが機能しない

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

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

15
Adil

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

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

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

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

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

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

50
Sergey Grinev

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

Platform.runLater(()->myTextField.requestFocus());
9
Sedrick

RequestFocus();の場合シーンを初期化した後、それは機能します!

このような:

Stage stage = new Stage();
GridPane grid = new GridPane();
//... add buttons&stuff to pane

Scene scene = new Scene(grid, 800, 600);

TEXTFIELD.requestFocus();

stage.setScene(scene);
stage.show();

これがお役に立てば幸いです。 :)

8
codepleb

これは、Nodeの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に翻訳したいと思うでしょう。

0
nickthecoder