小智 18
最简单的解决方案是编辑FXML文件并适当地重新排序容器.例如,我当前的应用程序有一个注册对话框,可以在其中输入序列号.为此目的有5个文本字段.为了使焦点从一个文本字段正确传递到另一个文本字段,我必须以这种方式列出它们:
<TextField fx:id="tfSerial1" layoutX="180.0" layoutY="166.0" prefWidth="55.0" />
<TextField fx:id="tfSerial2" layoutX="257.0" layoutY="166.0" prefWidth="55.0" />
<TextField fx:id="tfSerial3" layoutX="335.0" layoutY="166.0" prefWidth="55.0" />
<TextField fx:id="tfSerial4" layoutX="412.0" layoutY="166.0" prefWidth="55.0" />
<TextField fx:id="tfSerial5" layoutX="488.0" layoutY="166.0" prefWidth="55.0" />
Run Code Online (Sandbox Code Playgroud)
小智 13
Bluehair的答案是对的,但即使在JavaFX Scene Builder中也可以这样做.
左列中有"层次结构"面板.场景中有你的所有组件.它们的顺序代表焦点遍历顺序,它响应它们在FXML文件中的顺序.
我在这个网页上找到了这个小贴士:www.wobblycogs.co.uk
Ale*_*rov 12
在通常情况下,导航以容器顺序,按子女的顺序或按箭头键按下完成.您可以更改节点的顺序 - 在这种情况下,它将是您的最佳解决方案.
JFX中有一个关于遍历引擎策略替换的后门:
你可以继承内部类com.sun.javafx.scene.traversal.TraversalEngine
engine = new TraversalEngine(this, false) {
@Override public void trav(Node owner, Direction dir) {
// do whatever you want
}
};
Run Code Online (Sandbox Code Playgroud)
并使用
setImpl_traversalEngine(engine);
Run Code Online (Sandbox Code Playgroud)
打电话申请该引擎.
您可以观察OpenJFX的代码,了解它,它是如何工作的,以及您可以做些什么.
要非常小心:它是一个内部API,可能会在最近的将来发生变化.所以不要依赖于此(无论如何你不能依靠这个官方).
示例实施:
public void start(Stage stage) throws Exception {
final VBox vb = new VBox();
final Button button1 = new Button("Button 1");
final Button button2 = new Button("Button 2");
final Button button3 = new Button("Button 3");
TraversalEngine engine = new TraversalEngine(vb, false) {
@Override
public void trav(Node node, Direction drctn) {
int index = vb.getChildren().indexOf(node);
switch (drctn) {
case DOWN:
case RIGHT:
case NEXT:
index++;
break;
case LEFT:
case PREVIOUS:
case UP:
index--;
}
if (index < 0) {
index = vb.getChildren().size() - 1;
}
index %= vb.getChildren().size();
System.out.println("Select <" + index + ">");
vb.getChildren().get(index).requestFocus();
}
};
vb.setImpl_traversalEngine(engine);
vb.getChildren().addAll(button1, button2, button3);
Scene scene = new Scene(vb);
stage.setScene(scene);
stage.show();
}
Run Code Online (Sandbox Code Playgroud)
普通案件需要强大的分析能力;)
小智 7
我们正在使用JavaFX事件过滤器,例如:
cancelButton.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.TAB && event.isShiftDown()) {
event.consume();
getDetailsPane().requestFocus();
}
}
});
Run Code Online (Sandbox Code Playgroud)
该event.consume()抑制的默认焦点遍历,当调用否则会造成麻烦requestFocus().
这是适应内部api更改的公认答案(发生在fx-8的某个点,我目前的版本是8u60b5).显然原来的免责声明仍然适用:它是内部 API,随时可以随时更改,恕不另行通知!
变化(与接受的答案相比)
示例代码的简单翻译:
/**
* Requirement: configure focus traversal
* old question with old hack (using internal api):
* http://stackoverflow.com/q/15238928/203657
*
* New question (closed as duplicate by ... me ..)
* http://stackoverflow.com/q/30094080/203657
* Old hack doesn't work, change of internal api
* rewritten to new internal (sic!) api
*
*/
public class FocusTraversal extends Application {
private Parent getContent() {
final VBox vb = new VBox();
final Button button1 = new Button("Button 1");
final Button button2 = new Button("Button 2");
final Button button3 = new Button("Button 3");
Algorithm algo = new Algorithm() {
@Override
public Node select(Node node, Direction dir,
TraversalContext context) {
Node next = trav(node, dir);
return next;
}
/**
* Just for fun: implemented to invers reaction
*/
private Node trav(Node node, Direction drctn) {
int index = vb.getChildren().indexOf(node);
switch (drctn) {
case DOWN:
case RIGHT:
case NEXT:
case NEXT_IN_LINE:
index--;
break;
case LEFT:
case PREVIOUS:
case UP:
index++;
}
if (index < 0) {
index = vb.getChildren().size() - 1;
}
index %= vb.getChildren().size();
System.out.println("Select <" + index + ">");
return vb.getChildren().get(index);
}
@Override
public Node selectFirst(TraversalContext context) {
return vb.getChildren().get(0);
}
@Override
public Node selectLast(TraversalContext context) {
return vb.getChildren().get(vb.getChildren().size() - 1);
}
};
ParentTraversalEngine engine = new ParentTraversalEngine(vb, algo);
// internal api in fx8
// vb.setImpl_traversalEngine(engine);
// internal api since fx9
ParentHelper.setTraversalEngine(vb, engine);
vb.getChildren().addAll(button1, button2, button3);
return vb;
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent()));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26130 次 |
| 最近记录: |