消防按钮与JavaFX中输入的OnAction

问题描述 投票:12回答:3

我是一个新手到了JavaFx。在我的JavaFX应用程序我已经设置OnAction属性,当我按下鼠标使用的按钮,它工作正常。我想,即使火一样,当用户按下按钮进入。我知道我可以使用,甚至处理做到这一点。但是,当我读到的OnAction的JavaDoc它说,此事件由按键起火。

楼盘介绍:

按钮的动作,每当按钮被触发时被调用。这可能是由于在用鼠标按钮的用户点击,或由触摸事件,或由按键,或者如果显影剂编程调用火()方法。

但是,当我按下回车键没有反应。它是在文档中的错误?是否有任何其他的方式来实现,如果没有添加alistener的按钮?

P.S

评论后,我用空格键选中,那么它会被解雇。但我想设置到Enter键。我有许多按钮。我试图button.setDefaultButton(true);但它不会被解雇。我认为这是becacuse有多个按钮。如果我把它只是一个按钮,它工作正常。如何设置多个按钮?

java events button javafx action
3个回答
9
投票

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

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

0
投票

如果要将此应用到每一个按键在程序中你也可以继承的JavaFX的按钮,并在构造函数中绑定此。在您的FXML-文件,将需要包括您的自定义按钮。

我写了下面的子类:

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-文件自定义类:

<?import your-package.*?>

如果你想使用场景生成器事情变得更加困难一点:你需要导出自定义按钮在一个jar文件,并添加这场景生成器所描述的here


0
投票

为什么我总是回答三个岁的问题...?! ;-)不管怎么说,有人可能会发现它很有用(包括我自己)。

要覆盖输入我用下面称其为场景的按键事件过滤功能按键的行为:

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

基于事件的目标功能的工作原理如下。对于文本区域或TableView中,这是一个空操作。对于一个按钮,它占用的输入按事件和火灾空格键按下和释放事件。而对于所有其他控件,它也消耗了进入新闻发布会,并触发一个Tab事件,因此按Enter键将焦点移到下一个控件就像标签。

然后你只需注册整个场景的事件过滤器:

    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;
}
© www.soinside.com 2019 - 2024. All rights reserved.