为了覆盖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;
}
overrideEnterKeyPressEvent(evt);
break;
...
default:
break;
}
}
----- 因为我忘记包含isAncestorNodeTargeted()函数而进行编辑;感谢您的评论,Robert -----
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;
}