JavaFX TextField OnKeyTyped 无法正常工作

JavaFX TextField OnKeyTyped Not Working Properly

给定

JavaFX 应用程序,输入 TextField 并提交 Button

TextField 附加了一个 EventHandler,因此如果没有输入文本,Button 应该被禁用,反之亦然。

这是我的代码:

button.setDisable(true); // initially disabled
textField.setOnKeyTyped(new EventHandler<KeyEvent>() {
       @Override
       public void handle(KeyEvent event) {
            if (textField.getText().trim().isEmpty()) { // if blank textfield
                 button.setDisable(true);
            } else {
                 button.setDisable(false); 
             }
        }
});

两个控件都已正确初始化。据我所知,KeyTyped 和 KeyPressed/Released 之间的区别在于 Typed 用于实际可以键入和显示的字符;而 Pressed/Released 适用于任何键盘键,包括 Ctrl、Alt...

问题

我输入了textField一个字符,button仍然无效!如果我输入 2 个或更多字符,它就会启用!

但是,当我执行以下操作时:

button.setDisable(true);
textField.setOnKeyReleased(
    /*
     exact same code as above
    */
);

我的问题就解决了。

问题

为什么?我的代码中的缺陷在哪里?为什么 KeyTyped 不能按预期工作?

问题是:在你处理KeyEvent的时候,不确定你的TextFieldtextProperty有没有更新。

TextFieldtextProperty 添加侦听器的更清洁和更安全的方法,以便在 TextField 的文本更改时收到通知。想象一下用户粘贴一些内容的用例:在这种情况下根本没有 KeyEvent,因此你的 Button 仍然被禁用。

在 textProperty() 上使用侦听器

button.setDisable(true);
textField.textProperty().addListener((obj, oldVal, newVal) -> {

    if (newVal.trim().isEmpty()) { // if blank textfield
         button.setDisable(true);
    } else {
         button.setDisable(false); 
     }
});

...甚至更短...

button.setDisable(true);
textField.textProperty().addListener((obj, oldVal, newVal) -> button.setDisable(newVal.trim().isEmpty()));

但是,更简洁的解决方案是在 ButtondisableProperty 和 [=15 的 textProperty 之间使用绑定=].

使用 disablePropertytextProperty

之间的绑定
BooleanBinding textIsEmpty = Bindings.createBooleanBinding(() -> textField.getText().trim().isEmpty(), textField.textProperty());
button.disableProperty().bind(textIsEmpty);