简体   繁体   English

(JavaFX)绑定textProperty()时无法使用控件吗?

[英](JavaFX) Unable to use controls when binding the textProperty()?

I'm just getting started in learning property binding. 我刚刚开始学习属性绑定。 I have my controls set and the properties bound here (code abbreviated): 我设置了控件,并在此处绑定了属性(代码缩写):

@FXML
    private TextField txtOldPremium;
    @FXML
    private TextField txtNewPremium;
    @FXML
    private TextField txtProratedChange;

    private SimpleBooleanProperty quoteOnly = new SimpleBooleanProperty();
    private SimpleBooleanProperty reviewedBilling = new SimpleBooleanProperty();
    private SimpleStringProperty oldPremium = new SimpleStringProperty();
    private SimpleStringProperty newPremium = new SimpleStringProperty();
    private SimpleStringProperty proratedChange = new SimpleStringProperty();
    private SimpleStringProperty additionalInformation = new SimpleStringProperty();

    @FXML
    public void initialize() {

        // Bind the vehicle data to the tableview
        colEffectiveDate.setCellValueFactory(new PropertyValueFactory<Vehicle, String>("effectiveDateString"));
        colDescription.setCellValueFactory(new PropertyValueFactory<Vehicle, String>("description"));
        colVIN.setCellValueFactory(new PropertyValueFactory<Vehicle, String>("vin"));
        colAction.setCellValueFactory(new PropertyValueFactory<Vehicle, String>("action"));

        // Setup data binding to controls
        chkQuoteOnly.selectedProperty().bindBidirectional(quoteOnly);
        chkReviewedBilling.selectedProperty().bindBidirectional(reviewedBilling);
        txtOldPremium.textProperty().bindBidirectional(oldPremium);
        txtNewPremium.textProperty().bindBidirectional(newPremium);
    }

    @Override
    public String getComments() {
        StringBuilder comments = new StringBuilder();

        if (!txtOldPremium.getText().isEmpty() && !txtNewPremium.getText().isEmpty()) {

        } else {

            }
        }
        if (!txtProratedChange.getText().isEmpty()) {

        }

I am getting a NullPointerException at if (!txtOldPremium.getText().isEmpty() && !txtNewPremium.getText().isEmpty()) { . 我在if (!txtOldPremium.getText().isEmpty() && !txtNewPremium.getText().isEmpty()) {时收到NullPointerException。 I am assuming I am doing something radically wrong with implementing the bindings. 我假设我在实现绑定方面做的根本错误。 The TextFields themselves are currently empty. TextFields本身当前为空。

Basically, I just want the TextField and the oldPremium String to always remain in sync with eachother. 基本上,我只希望TextFieldoldPremium String始终保持彼此同步。 But I still need to be able to do processing on the text TextField . 但是我仍然需要能够对文本TextField进行处理。 I do have several other types of controls ( CheckBox , ComboBox , etc) that I want to have sync with the underlying data. 我确实还有其他几种类型的控件( CheckBoxComboBox等),它们希望与基础数据同步。

You are binding the text properties of the text fields to StringProperty instances that have been created without an initial value. 您正在将文本字段的文本属性绑定到没有初始值创建的StringProperty实例。 So, for example, when you do 因此,例如,当您

private SimpleStringProperty oldPremium = new SimpleStringProperty();

you create oldPremium without an actual value. 您创建的oldPremium没有实际值。 So oldPremium.getValue() will return null . 因此oldPremium.getValue()将返回null

So then when you do 所以当你这样做

txtOldPremium.textProperty().bindBidirectional(oldPremium);

you synchronize the state of the two properties ( txtOldPremium.textProperty() and oldPremium ), which involves copying the value of oldPremium (which is null ) into txtOldPremium.textProperty() . 您需要同步两个属性( txtOldPremium.textProperty()oldPremium )的状态,这涉及将oldPremium的值(为null )复制到txtOldPremium.textProperty()

So just initialize the properties to hold an empty string, instead of null: 因此,只需初始化属性即可容纳一个空字符串,而不是null:

private SimpleStringProperty oldPremium = new SimpleStringProperty("");

etc. 等等

Also, though, note that in this particular example you can achieve the same thing without duplicating all the properties. 此外,尽管如此,请注意,在此特定示例中,您可以实现相同的操作而无需复制所有属性。 Ie you can just do 即你可以做

private StringProperty oldPremium ;

// ...

@FXML
public void initialize() {

    // ...

    oldPremium = txtOldPremium.textProperty();

    // ...

}

You can still define property accessor methods 您仍然可以定义属性访问器方法

public StringProperty oldPremiumProperty() {
    return oldPremium ;
}

public final String getOldPremium() {
    return oldPremiumProperty().get();
}

public final void setOldPremium(String oldPremium) {
    oldPremiumProperty().set(oldPremium);
}

as you presumably already have, and it will have exactly the same effect, but with less overhead. 正如您可能已经拥有的那样,它将具有完全相同的效果,但开销却更少。

Bidirectional bindings are really most useful for synchronizing properties that belong to two different objects (eg properties belonging to different controllers, or to a controller and a model). 双向绑定对于同步属于两个不同对象的属性(例如,属于不同控制器,或控制器和模型的属性)确实非常有用。 Maybe your question reduced the code to demonstrate the problem, but I thought I would point this out for other users. 也许您的问题简化了代码来演示问题,但是我想我会为其他用户指出这一点。

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

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