无论值属性如何更改,都将调用ComboBox的输入键/操作事件处理程序 [英] Invoke a ComboBox's enter key/action event handler regardless of value property change

查看:481
本文介绍了无论值属性如何更改,都将调用ComboBox的输入键/操作事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用可编辑的 ComboBox ,是否有任何方式让ENTER键事件或操作事件处理程序发生,而不管 Combobox 的值属性已更改?

With an editable ComboBox, is there any way to have the ENTER key event or action event handler occur regardless of whether or not the Combobox's value property has changed?

我本质上想在 ComboBox ' TextField 在输入 TextField 时按ENTER键。

I essentially would like to have the same behaviour in a ComboBox's TextField on pressing the ENTER key as it occurs for a TextField.

我最初的想法是简单地使用 setOnAction ComboBox ;但是,根据它的文档:

My initial thought was to simply use setOnAction for a ComboBox; however, according to the documentation for it:


ComboBox操作,当ComboBox值属性更改时调用。这可能是由于当用户在弹出列表或对话框中选择项目时,或者在可编辑的组合框的情况下,用户提供他们自己的输入(通过文本框或一些其他输入机制。

The ComboBox action, which is invoked whenever the ComboBox value property is changed. This may be due to the value property being programmatically changed, when the user selects an item in a popup list or dialog, or, in the case of editable ComboBoxes, it may be when the user provides their own input (be that via a TextField or some other input mechanism.

因此,通过使用 setOnAction 处理程序仅在以下情况下发生:

Thus, by using setOnAction, the event handler only occurs if:


  1. 通过更改选择从
    下拉菜单更改value属性

  2. 通过用户输入更改value属性(即:如果用户没有输入任何内容,则不会出现
    ,如果用户没有输入则按ENTER键也不会出现
    在事件处理程序运行
    一次后更改其输入,然后按ENTER键。

$ c> ' <$ h> <$ c> <$ c> setOnAction https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#setOnKeyPressed-javafx.event.EventHandler-rel =nofollow> setOnKeyPressed 达到所需的行为。

Also, neither using setOnAction on the ComboBox's TextField nor using setOnKeyPressed achieves the desired behaviour.

以下是一个SSCCE,用于演示:

Below is an SSCCE to demonstrate:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Example extends Application {

    @Override
    public void start(Stage primaryStage) {
        ComboBox<String> comboBox =
            new ComboBox<String>(
                    FXCollections.observableArrayList("XYZ", "ABC"));
        comboBox.setEditable(true);
        comboBox.setValue(comboBox.getValue());
        comboBox.setOnAction((event) -> System.out
                .println("occurs on selection changes or text changes and ENTER key"));
        comboBox.getEditor().setOnAction(
                (event) -> System.out.println("this never happens"));
        comboBox.getEditor().setOnKeyPressed((keyEvent) -> {
            if (keyEvent.getCode() == KeyCode.ENTER)
                System.out.println("this never happens either");
        });

        TextField tf = new TextField();
        tf.setOnAction((event) -> System.out.println("always happens on ENTER"));

        HBox hbox = new HBox(comboBox, tf);

        Scene scene = new Scene(hbox);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}


推荐答案

一个通用的方式了解事件如何工作,你可以随时添加一个eventfilter与Event.ANY,看看会发生什么, g。:

As a general way of finding out how eventing works, you could always add an eventfilter with Event.ANY and see what happens, e. g.:

comboBox.getEditor().addEventFilter(Event.ANY, e -> System.out.println(e));

事件被触发,可以在控制台中看到。所以你需要的是添加一个过滤器的关键代码像这样:

The event gets fired, as can be seen in the console. So what you need is to add a filter for the key code like this:

comboBox.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, e -> {

    if (e.getCode() == KeyCode.ENTER) {
        System.out.println( "Enter pressed");
    }

});

关于你的问题,你可以看看ComboBoxListViewSkin,你可以看到事件被消耗。 / p>

Regarding your problem you can take a look at ComboBoxListViewSkin where you can see that the event is consumed.

private EventHandler<KeyEvent> textFieldKeyEventHandler = event -> {
    if (textField == null || ! getSkinnable().isEditable()) return;
    handleKeyEvent(event, true);
};

...

private void handleKeyEvent(KeyEvent ke, boolean doConsume) {
    // When the user hits the enter or F4 keys, we respond before
    // ever giving the event to the TextField.
    if (ke.getCode() == KeyCode.ENTER) {
        setTextFromTextFieldIntoComboBoxValue();

        if (doConsume) ke.consume();
    } 
    ...
}

使用EventFilter而不是EventHandler。

So in short: Use an EventFilter instead of an EventHandler.

您可以在处理JavaFX事件文档。

这篇关于无论值属性如何更改,都将调用ComboBox的输入键/操作事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆