To override the Enter key press behavior I use the function below calling it in the scene's key press event filter:
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();
}
Based on the event's target the function works as follows. For a TextArea or TableView, it's a NoOp. For a button, it consumes the Enter press event and fires Space key press and release events. And for all the other controls, it also consumes the Enter press event and fires a Tab event so pressing Enter moves focus to the next control just like Tab.
Then you just register an event filter for the whole scene:
scene.addEventFilter(KeyEvent.KEY_PRESSED, this::onSceneKeyPressedFilter);
And the event filter looks like:
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;
}
}
----- edit because I forgot to include the isAncestorNodeTargeted() function; thanks for the comment, 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;
}