【问题标题】:JavaFX TextField OnKeyTyped Not Working ProperlyJavaFX TextField OnKeyTyped 无法正常工作
【发布时间】:2016-10-17 15:25:41
【问题描述】:

给定

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 不能按预期工作?

【问题讨论】:

    标签: java javafx properties listener textfield


    【解决方案1】:

    问题是:在你处理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()));
    

    但是,在ButtondisablePropertyTextFieldtextProperty 之间使用绑定的更简洁的解决方案。

    使用disablePropertytextProperty 之间的绑定

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

    【讨论】:

    • 在您的第一个方法中,如果您使用ChangeListener (如(obj, oldVal, newVal) -&gt; { ...}),您甚至可以获得自动传递的新值,而无需再参考textField。无论如何,+1 ...
    • 好的。谢谢,尽管我仍然不明白为什么在一个字符上它不起作用,但在更多字符上它会起作用!
    • @rz3r0 简单:在调用setOnKeyTyped() 时,TextField 中的文本尚未更新。因此,您仍在读取旧(空)值。然后控件更新其文本并随后调用setOnKeyReleased() - 在那里,新值可用。
    • 感谢@AndreasFester指出lambda参数,我已经更新了答案,而且我刚刚注意到绑定不处理trim,所以这部分也更新了。
    猜你喜欢
    • 1970-01-01
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2022-11-11
    • 2013-12-21
    相关资源
    最近更新 更多