JavaFX:捕获“Enter”键被按下

4
我需要保留一个大小不确定的字符串列表。我认为最好的方法是通过组合框来实现,该组合框将接受用户输入,并在检测到“Enter”按键时将该用户输入添加到ComboBox项目列表中,并允许用户通过“Delete”按键删除这些项目。
我曾希望这将是一个非常简单的任务,处理方式如下:
    this.cbx.setOnKeyTyped((KeyEvent E) -> {
        switch(E.getCode()){
            case  ENTER:
                this.cbx.getItems().add(this.cbx.valueProperty().get());
                this.cbx.valueProperty().set("");
                E.consume();
                break;
            case DELETE:
                if (this.cbx.getItems().contains(
                    this.cbx.valueProperty().get()
                )) this.cbx.getItems().remove(this.cbx.valueProperty().get());
                this.cbx.valueProperty().set("");
                E.consume();
                break;
        }
    });

不幸的是,按下“Enter”键不会触发事件。所以我显然是错了。 我还尝试使用onKeyPressed,但也没有起作用。 我需要做什么才能捕捉到按下“Enter”和“Delete”键(它可以很好地捕捉到“Shift”键,这让人疯狂)。

编辑1:

也尝试过

If(E.getCode().Equals(KeyCode.ENTER)){
    ...
} else if (E.getCode().equals(KeyCode.DELETE)){
    ...
}

没有爱。

编辑2:

根据下面James_D的答案,它让我找到了正确的方向,为了实现我想要做的事情,我采用了以下方法:

    ComboBox<String> cb = new ComboBox<>();
    cb.setEditable(true);
    cb.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent E) -> {
        switch(E.getCode()){
            case ENTER:{
                if (cb.getItems().contains(cb.getEditor().getText()))
                    E.consume();
                else{
                    cb.getItems().add(cb.getEditor().getText());
                    cb.getEditor().clear();
                    E.consume();
                }
                break;
            }
            case DELETE:{
                if (E.isControlDown() && cb.getItems().contains(cb.getEditor().getText()))
                    cb.getItems().remove(cb.getEditor().getText());
                else if (E.isAltDown()) cb.getItems().clear();

                if (E.isControlDown() || E.isAltDown()){
                    cb.getEditor().clear();
                    E.consume();
                }
                break;
            }
        }
    });
1个回答

4

您是否希望拥有一个可编辑的组合框,当用户输入不在列表中的项时,可以将这些项添加到弹出列表中?

如果是这样,请尝试使用以下方法:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class UpdatingComboBox extends Application {

    @Override
    public void start(Stage primaryStage) {
        ComboBox<String> combo = new ComboBox<>();
        combo.setEditable(true);
        combo.valueProperty().addListener((obs, oldValue, newValue) -> {
            if (newValue != null && ! combo.getItems().contains(newValue)) {
                combo.getItems().add(newValue);
            }
        });
        HBox root = new HBox(combo);
        root.setAlignment(Pos.TOP_CENTER);
        primaryStage.setScene(new Scene(root, 350, 150));
        primaryStage.show();
    }

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

删除操作,我首先要问您的是,您是否真的需要按照您所描述的功能。用户通常会期望在可编辑组合框中按下“删除”键会删除下一个字符,而不是从列表中完全删除项目。如果您确实想这样做,您需要更深入地了解并使用键盘监听器。由于某些原因,将键盘监听器直接添加到组合框中似乎具有相当不可预测的结果;但如果您将其添加到可编辑组合框下层的文本字段中,则可以正常工作:

    combo.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, event -> {
        if (event.getCode() == KeyCode.DELETE) {
            combo.getItems().remove(combo.getValue());
            event.consume();
        }
    });

我预见到的唯一问题是,如果用户正在输入一个值,它不会像这样做吗?例如,如果我键入“Dog”,它不会添加“D”、“Do”、“Dog”吗?我需要能够一次性添加整个值,并且也需要能够一次性删除整个值。 - Will
你可以随时复制并粘贴代码,然后测试它。 - James_D
先生,您是正确的,由于某种原因,在“Enter”键上它确实起作用。我找到了一个关于在此处使用基于EventFilter的条目的条目(其中甚至带有您的姓名):http://tech.chitgoks.com/2013/08/15/java-fx-2-editable-combobox-does-not-detect-esc-enter-space-key/ 但那个行为非常奇怪。既然那个有效,那么如何从列表中删除值呢? - Will
感谢您的编辑。如果它有效,我会将其标记为正确,并且您是正确的,用户可能会期望这样。但是,“是否按下Ctrl”或“是否按下Ctrl-Alt”(对于热键清除)的简单检查将很好地处理该情况。 - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接