使用JavaFX中的Enter键触发按钮的onAction

我是JavaFx的新手。 在我的JavaFX应用程序中,我设置了onAction属性,当我使用鼠标按下按钮时,它工作正常。 即使用户按下Enter按钮,我也要发射相同的内容。 我知道我可以使用偶数处理程序来做到这一点。 但是当我阅读onAction JavaDoc时,它说这个事件会被按键发生。

楼盘简介:

按钮的动作,每当按钮被触发时都会调用它。 这可能是由于用户使用鼠标单击按钮,或通过触摸事件, 或通过按键 ,或者开发人员以编程方式调用fire()方法。

但是当我按下Enter键时没有任何反应。 在文档中是错误的吗? 如果不在按钮上添加alistener,还有其他方法可以实现吗?

PS

在评论后我用空格键检查然后它被解雇了。 但我想将其设置为Enter键。 我有很多按钮。 我试过了button.setDefaultButton(true); 但它不会被解雇。 我认为这是因为有多个按钮。 如果我只将它设置为一个按钮就可以了。 如何设置多个按钮?

您可以使用绑定动态更改当前聚焦按钮的默认按钮属性

 btn.defaultButtonProperty().bind(btn.focusedProperty()); 

如果要将它应用于程序中的每个Button,可以将JavaFX-Button子类化并在构造函数中绑定它。 在您的fxml-File中,您需要包含自定义Button。

我写了以下子类:

 public class FocusedButton extends javafx.scene.control.Button { public FocusedButton ( ) { super ( ); bindFocusToDefault ( ); } public FocusedButton ( String text ) { super ( text ); bindFocusToDefault ( ); } public FocusedButton ( String text, Node graphic ) { super ( text, graphic ); bindFocusToDefault ( ); } private void bindFocusToDefault ( ) { defaultButtonProperty().bind(focusedProperty()); } } 

要使用此代码,您需要在fxml-File中包含自定义类:

  

如果你想使用Scene Builder,事情会变得更加困难:你需要在jar文件中导出自定义Button并将其添加到Scene Builder中,如此处所述

为什么我总是回答三年的问题……?! ;-)无论如何,有人可能会觉得它很有用(包括我自己)。

要覆盖Enter键按下行为,我使用下面的函数在场景的按键事件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(); } 

根据事件的目标,该function的工作原理如下。 对于TextArea或TableView,它是NoOp。 对于按钮,它会消耗Enter press事件并触发Space键按下和释放事件。 对于所有其他控件,它还会消耗Enter按事件并触发Tab事件,因此按Enter键将焦点移动到下一个控件,就像Tab一样。

然后你只需为整个场景注册一个事件filter:

  scene.addEventFilter(KeyEvent.KEY_PRESSED, this::onSceneKeyPressedFilter); 

事件filter看起来像:

 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; } }