Javafx 关注容器中的下一项

Javafx 关注容器中的下一项,javafx,javafx-8,Javafx,Javafx 8,有没有一种方法可以通过编程将焦点集中在容器中的下一个可聚焦节点上,而不直接调用特定组件的方法?此功能类似于按tab按钮在跳过节点的组件之间遍历焦点。没有用于此功能的公共方法。只有黑客和变通办法 您可以使用节点的 impl_traverse(Direction.NEXT); 方法。但这一版本已被弃用,可以随时删除,您的代码会因新的java版本而中断 或者,您可以捕获enter键并触发tab键事件。但这同样丑陋 或者,如果您在文本字段中,您可以这样做: if( textfield.getSkin(

有没有一种方法可以通过编程将焦点集中在容器中的下一个可聚焦节点上,而不直接调用特定组件的方法?此功能类似于按tab按钮在跳过节点的组件之间遍历焦点。

没有用于此功能的公共方法。只有黑客和变通办法

您可以使用节点的

impl_traverse(Direction.NEXT);
方法。但这一版本已被弃用,可以随时删除,您的代码会因新的java版本而中断

或者,您可以捕获enter键并触发tab键事件。但这同样丑陋

或者,如果您在文本字段中,您可以这样做:

if( textfield.getSkin() instanceof BehaviorSkinBase) {
    ((BehaviorSkinBase) textfield.getSkin()).getBehavior().traverseNext();  
}
Method[] allMethods = scene.getClass().getDeclaredMethods();
for (Method m : allMethods) {
    String mname = m.getName();
    if (mname.startsWith("traverse")) {
        m.setAccessible(true);
        m.invoke(scene, new Object[] { textfield, Direction.NEXT });
    }
}
但这也令人沮丧,因为它不是api

即使使用反射来访问场景的遍历方法,如下所示:

if( textfield.getSkin() instanceof BehaviorSkinBase) {
    ((BehaviorSkinBase) textfield.getSkin()).getBehavior().traverseNext();  
}
Method[] allMethods = scene.getClass().getDeclaredMethods();
for (Method m : allMethods) {
    String mname = m.getName();
    if (mname.startsWith("traverse")) {
        m.setAccessible(true);
        m.invoke(scene, new Object[] { textfield, Direction.NEXT });
    }
}
您将不得不提供一个方向参数,这也是不鼓励的


您可以做的最好的事情是。

根据您的用例,您还可以筛选并转换父窗格上的“回车键到”选项卡:

@Override
public void start( final Stage primaryStage )
{
    TextField field1 = new TextField();
    TextField field2 = new TextField();
    TextField field3 = new TextField();
    VBox vbox = new VBox( field1, field2, field3 );

    vbox.addEventFilter( KeyEvent.KEY_PRESSED, ( KeyEvent event ) ->
    {
        if ( event.getCode() == KeyCode.ENTER )
        {
            KeyEvent newEvent
                    = new KeyEvent(
                            null,
                            null,
                            KeyEvent.KEY_PRESSED,
                            "",
                            "\t",
                            KeyCode.TAB,
                            event.isShiftDown(),
                            event.isControlDown(),
                            event.isAltDown(),
                            event.isMetaDown()
                    );

            Event.fireEvent( event.getTarget(), newEvent );
            event.consume();
        }
    } );
    final Scene scene = new Scene( vbox, 800, 600 );
    primaryStage.setScene( scene );
    primaryStage.show();

}

在为这个问题寻找了一个像样的答案之后,我终于写下了自己的答案,因为没有一个答案真正符合我的需要

这是我的解决方案(注意:我只使用文本字段,所以默认情况下,按下ENTER键时执行setOnAction):


为什么常规选项卡行为不适用于您?用户希望能够像使用选项卡键一样使用ENTER键来遍历字段。此外,他们希望ENTER键执行一些错误检查,TAB键跳过错误检查。我个人认为,我的表单在输入时使用
setOnAction()
,然后调用next input
requestFocus()
。已经有一个,您可能只想投票支持它(可能还需要对API的外观进行一些详细说明)。对于我的应用程序,我编写了一个类DoubleField,它扩展了TextField,并将此代码添加到构造函数方法中。这样我只需键入一次。它对我的所有字段都很有吸引力。