要覆盖 Enter 按键行为,我使用以下函数在场景的按键事件过滤器中调用它:
public static void overrideEnterKeyPressEvent(KeyEvent evt) {
EventTarget eventTarget = evt.getTarget();
if ((eventTarget instanceof TextArea) || (eventTarget instanceof TableView)) {
return;
}
if (eventTarget instanceof Button) {
Platform.runLater(() -> {
KeyEvent newEventPressed = new KeyEvent(KeyEvent.KEY_PRESSED, " ", " ", KeyCode.SPACE, false, false, false, false);
Event.fireEvent(eventTarget, newEventPressed);
KeyEvent newEventReleased = new KeyEvent(KeyEvent.KEY_RELEASED, " ", " ", KeyCode.SPACE, false, false, false, false);
Event.fireEvent(eventTarget, newEventReleased);
});
evt.consume();
return;
}
Platform.runLater(() -> {
KeyEvent tabEvent = new KeyEvent(KeyEvent.KEY_PRESSED, "", "\t", KeyCode.TAB, evt.isShiftDown(), false, false, false);
Event.fireEvent(eventTarget, tabEvent);
});
evt.consume();
}
根据事件的目标,函数的工作方式如下。对于 TextArea 或 TableView,它是 NoOp。对于按钮,它使用 Enter 按下事件并触发 Space 键按下和释放事件。对于所有其他控件,它还使用 Enter 按下事件并触发 Tab 事件,因此按下 Enter 会将焦点移动到下一个控件,就像 Tab 一样。
然后你只需为整个场景注册一个事件过滤器:
scene.addEventFilter(KeyEvent.KEY_PRESSED, this::onSceneKeyPressedFilter);
事件过滤器看起来像:
private void onSceneKeyPressedFilter(KeyEvent evt) {
switch (evt.getCode()) {
case ENTER:
if (evt.isControlDown() && FxTools.isAncestorNodeTargeted(evt.getTarget(), fxHBoxInputAp)) {
return; //let the events for the fxHBoxInputAp pane pass through
}
overrideEnterKeyPressEvent(evt);
break;
...
default:
break;
}
}
----- 编辑因为我忘记包含 isAncestorNodeTargeted() 函数;感谢您的评论,罗伯特 -----
public static boolean isDescendantOf(Node node, Node ancestor) {
while ((node != null) && (node != ancestor)) {
node = node.getParent();
}
return (node != null);
}
public static boolean isAncestorNodeTargeted(EventTarget target, Node ancestor) {
return (target instanceof Node) ? isDescendantOf((Node) target, ancestor) : false;
}