JavaFX TextField如何防止键在keypressed事件中输入

时间:2015-04-03 00:29:07

标签: events javafx event-handling textfield keyboard-events

我需要检测小键盘按键才能做一些事情。这是代码:

textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode().isKeypadKey()) {
                    //do stuff here...
                    event.consume();
                }
            }
        });

让我们说用户按下&#39; 2&#39;在小键盘上,尽管事件被消耗了,但是这个问题很简单。将出现在文本字段中。但我不想那样。任何想法如何防止这种情况?

更有意思的是,如果我抛出一个虚拟异常而不是消耗该事件,它将阻止keytyped事件。

1 个答案:

答案 0 :(得分:5)

您可以通过添加日志记录侦听器来解释您遇到的问题:

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

因此,当您输入密钥时,您会得到:

KeyEvent [source = TextField@42924cd[styleClass=text-input text-field], target = TextField@42924cd[styleClass=text-input text-field], eventType = KEY_PRESSED, consumed = false, character = , text = 1, code = NUMPAD1]
KeyEvent [source = TextField@42924cd[styleClass=text-input text-field], target = TextField@42924cd[styleClass=text-input text-field], eventType = KEY_TYPED, consumed = false, character = 1, text = , code = UNDEFINED]
KeyEvent [source = TextField@42924cd[styleClass=text-input text-field], target = TextField@42924cd[styleClass=text-input text-field], eventType = KEY_RELEASED, consumed = false, character = , text = 1, code = NUMPAD1]

换句话说,KeyTyped事件无法区分键盘按下(代码= UNDEFINED),因此您无法捕捉它。

它与异常一起工作的原因与只是在不检查任何内容的情况下使用事件的原因相同。您可以使用它并阻止输入。但是,不要使用键盘检查。

但话说回来,无论如何你都不应该阻止它。应该由用户决定他想要使用他的键盘或任何输入机制。

但如果必须,你必须。鉴于此信息,此问题的解决方法可能是:

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        HBox root = new HBox();

        EventHandler<KeyEvent> handler = new EventHandler<KeyEvent>() {

            private boolean willConsume = false;

            @Override
            public void handle(KeyEvent event) {

                if (willConsume) {
                    event.consume();
                }

                if (event.getCode().isKeypadKey()) {
                    if (event.getEventType() == KeyEvent.KEY_PRESSED) {
                        willConsume = true;
                    } else if (event.getEventType() == KeyEvent.KEY_RELEASED) {
                        willConsume = false;
                    }
                }
            }

        };

        TextField textField = new TextField();
        textField.addEventFilter(KeyEvent.ANY, handler);

        // logging
        textField.addEventFilter(KeyEvent.ANY, e -> System.out.println(e));

        root.getChildren().addAll(textField);

        Scene scene = new Scene(root, 300, 100);

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

    }

}

这是简单的版本。实际上你必须使用扩展机制才能处理多个按键。