2

JavaFX : フォーカス トラバーサル ポリシーを変更するには? Alexander Kirov が、JavaFX アプリケーションのフォーカストラバーサルポリシーをカスタマイズする方法を示しています。正常に動作しますが、TitledPanes では動作しません。のノードにTitledPaneフォーカスがある場合、settedTraversalEngineは呼び出されません。

この現象を示す完全な例を次に示します。

package org.example;

import com.sun.javafx.scene.traversal.Direction;
import com.sun.javafx.scene.traversal.TraversalEngine;

import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class FocusTest extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        // Create UI
        final VBox root = new VBox();
        final Button foo = new Button("foo");
        foo.setId("foo");
        root.getChildren().add(foo);
        final Button bar = new Button("bar");
        bar.setId("bar");
        final Pane content = new Pane();
        content.getChildren().add(bar);
        final TitledPane tp = new TitledPane("tp", content);
        root.getChildren().add(tp);

        // Set TraversalEngine
        final TraversalEngine te = new TraversalEngine(root, false) {
            @Override
            public void trav(Node owner, Direction direction) {
                System.out.printf("trav owner: %s, direction: %s%n",
                        owner.getId(), direction);
                switch (direction) {
                case DOWN:
                case RIGHT:
                case NEXT:
                    if (owner == foo) {
                        bar.requestFocus();
                    } else if (owner == bar) {
                        foo.requestFocus();
                    }
                    break;
                case LEFT:
                case PREVIOUS:
                case UP:
                    if (owner == foo) {
                        bar.requestFocus();
                    } else if (owner == bar) {
                        foo.requestFocus();
                    }
                    break;
                }
            }
        };
        root.setImpl_traversalEngine(te);

        // Show Scene
        final Scene scene = new Scene(root);
        primaryStage.setHeight(200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

シーンのルートは でVBox、カスタムTraversalEngineはそれに設定されています。ボタンfooにフォーカスがあり、[Tab] を押すte.travと、 が呼び出され、フォーカスが に設定されbarます。それが私が期待した方法です。しかしbar、フォーカスがあるときはte.trav呼び出されません。barの子ですTitledPane。この動作は1に示されています。

これに対する解決策はありますか?

TitledPane でのフォーカス トラバーサル

4

3 に答える 3

1

TitledPaneこれは、 sを扱うトリッキーなソリューションです。

@SuppressWarnings("deprecation")
private static void registerTraversalEngine(final Parent parent,
        final TraversalEngine te) {
    parent.setImpl_traversalEngine(te);
    for (Node child : parent.getChildrenUnmodifiable()) {
        if (child instanceof Parent) {
            registerTraversalEngine((Parent) child, te);
        }
    }
    if (parent instanceof TitledPane) {
        final TitledPane tp = (TitledPane) parent;
        if (tp.getContent() instanceof Parent) {
            registerTraversalEngine((Parent) tp.getContent(), te);
        }
    }
}

TitltedPanes の問題は、コンテンツが子セットにないことだと思います:

TitledPane.getChildrenUnmodifiable().contains(TitledPane.getContent()) is always false
于 2013-03-14T08:49:46.663 に答える
0

注目したいコンポーネントが Swing の場合、その requestFocus() をオーバーロードして、その SwingNode 親をコールバックするだけです。これ以上何もない :

    SwingNode n = new SwingNode() {

        @Override
        public void requestFocus() {
            System.err.println("SwingNode.requestFocus "); // just to check
            super.requestFocus();
        }
    };
    JTextArea p = new JTextArea() {

        @Override
        public void requestFocus() {
            System.err.println("JTextArea.requestFocus");
            n.requestFocus(); // <- HERE IS THE TRICK: use SwingNode focus instead of Swing component one
        }
    };
    n.setContent(p);
于 2015-04-01T19:42:46.760 に答える
0

フィールドに fx:id を保存します。

nombreDelPropietario.setUserData("#rbTodos");

On Action イベントにこの関数を設定します。

    

public void procesaEnter(ActionEvent event) {

        /* Obtiene el Objeto que recibió el Enter */

        Node source = (Node) event.getSource();

        /* Obtiene el ID del objeto al que hay que ir */

        String idDestino = (String) source.getUserData();

        /* Si está informado */

        if (idDestino != null) {

            /* Recupera el Nodo */

            Node destino = (Node) ((Scene) source.getScene()).lookup(idDestino);

            /* Si está el nodo activo, accede al nodo seleccionado */

            if (destino != null) {
                destino.requestFocus();
            }

        }

    }
于 2013-10-10T01:08:02.097 に答える