TextField和属性之间的JavaFX绑定

时间:2014-04-14 11:32:08

标签: java binding javafx textfield

如果在JavaFX TextField和属性之间创建绑定,则每次击键时此绑定都会失效,从而导致文本发生更改。

如果您有一系列绑定,默认行为可能会导致问题,因为在编辑过程中值可能无效。

好的,我知道我可以创建从属性到文本字段的单向绑定,并注册一个更改侦听器,以便在光标离开字段时获取通知,并在必要时手动更新属性。

是否有一种简单,优雅的方法来更改此行为,以便仅在编辑完成时无效,例如,当光标离开字段时?

由于

1 个答案:

答案 0 :(得分:2)

我认为你已经描述了实现它的唯一方法。这是关于我可以看到实现它的最干净的方法(使用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);
        }
    }