简体   繁体   English

TextField和属性之间的JavaFX绑定

[英]JavaFX binding between TextField and a property

If you create a binding between a JavaFX TextField and a property, then this binding is invalidated on every keystroke, which causes a change to the text. 如果在JavaFX TextField和属性之间创建绑定,则每次击键时此绑定都将失效,从而导致对文本进行更改。

If you have a chain of bindings the default behavior could cause problems, because in the middle of the editing values may be not valid. 如果您有一系列绑定,则默认行为可能会导致问题,因为在编辑中间值可能无效。

Ok, I know I could create an uni-directional binding from the property to the textfield and register a change listener to get informed when the cursor leaves the field and update the property manually if necessary. 好的,我知道我可以创建从属性到文本字段的单向绑定,并注册一个更改侦听器,以便在光标离开字段时获取通知,并在必要时手动更新属性。

Is there an easy, elegant way to change this behavior so that the binding is only invalidated when the editing is complete, eg when the cursor leaves the field? 是否有一种简单,优雅的方法来更改此行为,以便绑定仅在编辑完成时失效,例如当光标离开字段时?

Thanks 谢谢

I think you've pretty much described the only way to do it. 我认为你已经描述了唯一的方法。 Here's about the cleanest way I can see to implement it (using Java 8, though it's easy enough to convert the lambdas back to be JavaFX 2.2 compatible if you need): 这是关于我可以看到实现它的最简洁方法(使用Java 8,尽管如果需要,将lambda重新转换为JavaFX 2.2兼容)很简单:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

    public class CommitBoundTextField extends Application {

        @Override
        public void start(Stage primaryStage) {
            TextField tf1 = new TextField();
            createCommitBinding(tf1).addListener((obs, oldText, newText) -> 
                System.out.printf("Text 1 changed from \"%s\" to \"%s\"%n", oldText, newText));
            TextField tf2 = new TextField();
            createCommitBinding(tf2).addListener((obs, oldText, newText) -> 
                System.out.printf("Text 2 changed from \"%s\" to \"%s\"%n", oldText, newText));
            VBox root = new VBox(5, tf1, tf2);
            Scene scene = new Scene(root, 250, 100);
            primaryStage.setScene(scene);
            primaryStage.show();
        }

        private StringBinding createCommitBinding(TextField textField) {
            StringBinding binding = Bindings.createStringBinding(() -> textField.getText());
            textField.addEventHandler(ActionEvent.ACTION, evt -> binding.invalidate());
            textField.focusedProperty().addListener((obs, wasFocused, isFocused)-> {
                if (! isFocused) binding.invalidate();
            });
            return binding ;
        }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM