有没有办法以编程方式关注容器中的下一个可聚焦节点,而无需直接调用特定组件的requestFocus()
方法?此功能类似于按Tab键按钮在跳过disabled
个节点的组件之间遍历焦点。
答案 0 :(得分:8)
没有公开的方法。 只有黑客和解决方法。
您可以使用节点的
impl_traverse(Direction.NEXT);
方法。但是这个版本已被弃用,可以随时删除,并且您的代码会破坏新的java版本。
或者,您可以捕获回车键并触发Tab键事件。但那同样很难看。
或者,如果您在文本字段中,则可以这样做:
if( textfield.getSkin() instanceof BehaviorSkinBase) {
((BehaviorSkinBase) textfield.getSkin()).getBehavior().traverseNext();
}
但这也是因为它不是api而气馁。
即使您使用反射来访问场景的遍历方法,如下所示:
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 });
}
}
你最终必须提供一个也不鼓励的Direction参数。
你能做的最好的事情是comment and vote on this issue。
答案 1 :(得分:4)
根据您的使用案例,您还可以在父窗格中过滤 Enter 键并转换为 Tab :
@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();
}
答案 2 :(得分:0)
在搜索并寻找这个问题的正确答案之后,我终于写下了自己的答案,因为没有答案能真正满足我的需求。
这是我的解决方案(注意:我只使用TextFields,因此默认情况下setOnAction在按下ENTER时执行):
textField.setOnAction((ActionEvent e) -> {
boolean isThisField = false;
for (Node child : textField.getParent().getChildrenUnmodifiable()) {
if (isThisField) {
//This code will only execute after the current Node
if (child.isFocusTraversable() && !child.isDisabled()) {
child.requestFocus();
//Reset check to prevent later Node from pulling focus
isThisField = false;
}
} else {
//Check if this is the current Node
isThisField = child.equals(textField);
}
}
//Check if current Node still has focus
boolean focusChanged = !textField.isFocused();
if (!focusChanged) {
for (Node child : textField.getParent().getChildrenUnmodifiable()) {
if (!focusChanged && child.isFocusTraversable() && !child.isDisabled()) {
child.requestFocus();
//Update to prevent later Node from pulling focus
focusChanged = true
}
}
}
});