使用标签和按钮管理焦点 - 在标签中显示按键
Managing focus with label and buttons - Display key press in label
当我在下面使用术语非活动节点时,我的意思是不应该与用户交互的东西。
我构建了一个类似于此的通用登录屏幕:
一个标签,数字键上方的打字标签既接受按钮输入又接受键盘输入。按照我到目前为止的设计方式,标签会捕获键盘的按键操作,因此必须保持焦点。用户不应通过单击它以使其接受按键来保持对此标签的关注。
其余标签应该处于非活动状态:"LOGIN" 标题、"Enter Employee Number" 消息以及日期和时间标签。
按钮都是交互式的:数字按钮、后退按钮、清除按钮、提交按钮和重置按钮。单击这些按钮时,它们会编辑键入标签文本并将焦点传回给它。
最后,应该有非活动容器持有这些节点。
显示此屏幕时,我希望用户能够在键入标签中键入数字,即使他们有意尝试将焦点从标签上移开。我可以让屏幕上的每个单独节点 node.mouseTransparent(boolean type);
或 node.focusTraversable(boolean type)
,但似乎应该有更好的方法来做到这一点。
如果不希望用户管理焦点,那么在具有非活动节点和交互节点的屏幕中记录按键和管理焦点的最佳方式是什么?
我想做这样的事情:
parent.mouseTransparent(true);
interactiveChild.mouseTransparent(false);
因为我希望 parent 代码能够涵盖非活动 children 的分类,但交互式 child 仍然无法点击。
您可以简单地在布局级别或场景级别为 KeyEvent
添加一个事件过滤器,并自己处理数字键的事件:
@Override
public void start(Stage primaryStage) throws Exception {
GridPane grid = new GridPane();
TextField textField = new TextField();
grid.add(textField, 0, 0, 3, 1);
for (int i = 0; i < 9; i++) {
Button button = new Button(Integer.toString(9 - i));
button.setOnAction(evt -> textField.appendText(button.getText()));
grid.add(button, i % 3, i / 3 + 1);
}
Button button = new Button("0");
button.setOnAction(evt -> textField.appendText("0"));
grid.add(button, 1, 4);
grid.addEventFilter(KeyEvent.ANY, evt -> {
// consume every press of a digit key and handle the release for
// adding the text
if (evt.getEventType() == KeyEvent.KEY_TYPED) {
String text = evt.getCharacter();
if (text.length() == 1 && Character.isDigit(text.charAt(0))) {
evt.consume();
textField.appendText(text);
}
} else if (evt.getCode().isDigitKey()) {
evt.consume();
}
});
Scene scene = new Scene(grid);
primaryStage.setScene(scene);
primaryStage.show();
}
费边说的。您的意思是,只要 JavaFX 应用程序具有焦点,您就希望将击键定向到提交按钮旁边的字段中。
您需要一个包含其他元素的窗格的关键侦听器。您需要其他元素不取消任何击键事件,以便它们在冒泡阶段或滴流阶段到达您。您需要侦听器能够直接或间接(通过另一个对象)访问要出现击键的字段。您需要侦听器获取它接收到的击键并将它们放入该字段。您可以手动或通过将捕获的击键事件定向到该字段来执行此操作。
当然,您还需要检查以确保它们是合法的(在您的情况下是数字?)以及您希望此小部件具有的任何其他行为。
希望这能让您大致了解要写什么以及如何实现您的目标。
当我在下面使用术语非活动节点时,我的意思是不应该与用户交互的东西。
我构建了一个类似于此的通用登录屏幕:
一个标签,数字键上方的打字标签既接受按钮输入又接受键盘输入。按照我到目前为止的设计方式,标签会捕获键盘的按键操作,因此必须保持焦点。用户不应通过单击它以使其接受按键来保持对此标签的关注。
其余标签应该处于非活动状态:"LOGIN" 标题、"Enter Employee Number" 消息以及日期和时间标签。
按钮都是交互式的:数字按钮、后退按钮、清除按钮、提交按钮和重置按钮。单击这些按钮时,它们会编辑键入标签文本并将焦点传回给它。
最后,应该有非活动容器持有这些节点。
显示此屏幕时,我希望用户能够在键入标签中键入数字,即使他们有意尝试将焦点从标签上移开。我可以让屏幕上的每个单独节点 node.mouseTransparent(boolean type);
或 node.focusTraversable(boolean type)
,但似乎应该有更好的方法来做到这一点。
如果不希望用户管理焦点,那么在具有非活动节点和交互节点的屏幕中记录按键和管理焦点的最佳方式是什么?
我想做这样的事情:
parent.mouseTransparent(true);
interactiveChild.mouseTransparent(false);
因为我希望 parent 代码能够涵盖非活动 children 的分类,但交互式 child 仍然无法点击。
您可以简单地在布局级别或场景级别为 KeyEvent
添加一个事件过滤器,并自己处理数字键的事件:
@Override
public void start(Stage primaryStage) throws Exception {
GridPane grid = new GridPane();
TextField textField = new TextField();
grid.add(textField, 0, 0, 3, 1);
for (int i = 0; i < 9; i++) {
Button button = new Button(Integer.toString(9 - i));
button.setOnAction(evt -> textField.appendText(button.getText()));
grid.add(button, i % 3, i / 3 + 1);
}
Button button = new Button("0");
button.setOnAction(evt -> textField.appendText("0"));
grid.add(button, 1, 4);
grid.addEventFilter(KeyEvent.ANY, evt -> {
// consume every press of a digit key and handle the release for
// adding the text
if (evt.getEventType() == KeyEvent.KEY_TYPED) {
String text = evt.getCharacter();
if (text.length() == 1 && Character.isDigit(text.charAt(0))) {
evt.consume();
textField.appendText(text);
}
} else if (evt.getCode().isDigitKey()) {
evt.consume();
}
});
Scene scene = new Scene(grid);
primaryStage.setScene(scene);
primaryStage.show();
}
费边说的。您的意思是,只要 JavaFX 应用程序具有焦点,您就希望将击键定向到提交按钮旁边的字段中。
您需要一个包含其他元素的窗格的关键侦听器。您需要其他元素不取消任何击键事件,以便它们在冒泡阶段或滴流阶段到达您。您需要侦听器能够直接或间接(通过另一个对象)访问要出现击键的字段。您需要侦听器获取它接收到的击键并将它们放入该字段。您可以手动或通过将捕获的击键事件定向到该字段来执行此操作。
当然,您还需要检查以确保它们是合法的(在您的情况下是数字?)以及您希望此小部件具有的任何其他行为。
希望这能让您大致了解要写什么以及如何实现您的目标。