如果它不是String属性,是否可以将TextProperty绑定到ObjectProperty的String属性?

时间:2019-06-03 19:03:35

标签: java javafx data-binding properties object-property

如何在不使用ObjectProperty的情况下将TextField的属性(本身不是属性)绑定到其他属性,例如ChangeListener的text属性?

更具体地说:

我想使TextField更改ObjectProperty的属性。

示例代码:

MapDTO:

public class MapDTO {
    private String cityName;

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }
}

MapsManager:

public class MapsManager {

    private static ObjectProperty<MapDTO> map = new SimpleObjectProperty<>();

    public static MapDTO getMap() {
        return map.get();
    }

    public static ObjectProperty<MapDTO> mapProperty() {
        return map;
    }

    public static void setMap(MapDTO map) {
        MapsManager.map.set(map);
    }
}

BindingTestController:

public class BindingTestController {

    private TextField cityNameTF = new TextField();

    private void initialize() {

        // Bind the cityName label to the selected MapsManager mapProperty's cityName   
        cityNameTF.textProperty().bind(Bindings.createStringBinding(
            () -> MapsManager.mapProperty().getValue() == null ? null :
                MapsManager.mapProperty().getValue().getCityName(),
            MapsManager.mapProperty()));
    }
}

我已经尝试过:

从选定的值String属性创建一个字符串属性,但是没有成功,而且我找不到正确的方法。

cityNameTF.textProperty().bindBidirectional(Bindings.createStringBinding(
() -> selectMapCB.getValue() == null ? null : selectMapCB.getValue().getCityName(), 
selectMapCB.valueProperty()));

从mapProperty的String属性创建字符串属性。

cityNameTF.textProperty().bindBidirectional(Bindings.createStringBinding(
() -> MapsManager.getMapProperty().getValue() == null ? null : MapsManager.mapProperty().getValue().getCityName(),
MapsManager.mapProperty()));

两个选项都给出相同的错误:

bindBidirectional (javafx.beans.property.Property<java.lang.String>)
in StringProperty cannot be applied to (javafx.beans.binding.StringBinding)

在两种情况下都可以用bindBidirectional替换bind,但是我不能更改TextField中的文本。 我意识到这是因为我正在将TextField的文本绑定到cityName的字符串。所以我想以一种相反的方向绑定它,像这样:

MapsManager.mapProperty().????.bind(cityNameTF.textProperty());

但是“ ????” -我没有String的属性,即使可能,也不知道如何动态创建StringBindingStringProperty

如何在ObjectProperty的属性和另一个StringProperty的属性之间手动创建字符串绑定?

1 个答案:

答案 0 :(得分:0)

您的MapDTO本质上是JavaBean-带有字段及其获取器和设置器的类。我们将此类字段称为 bean属性。由于您不能绑定到这些属性或从这些属性绑定,因此JavaFX提供了将它们桥接到JavaFX属性的适配器。它们位于软件包javafx.beans.property.adapter中:

  

提供各种类,这些类充当常规Java Bean属性和相应的JavaFX属性之间的适配器。

在内部,它们充当bean属性的包装器。

由于您的MapDTO包含String,因此我们将使用JavaBeanStringProperty。请注意:

  

至少,Java Bean类必须为该属性实现getter和setter。该类以及getter和setter方法必须声明为公共。

所以我们遵守要求。

在这种情况下,我们使用其构建器JavaBeanStringPropertyBuilder创建了这些适配器:

JavaBeanStringProperty cityNameProperty = JavaBeanStringPropertyBuilder.create()
                                              .bean(MapsManager.getMap())
                                              .name("cityName")
                                              .build();

构建器以反射方式访问数据。现在,我们可以照常使用创建的属性:

cityNameProperty.bind(cityNameTF.textProperty());

,对文本字段的text属性所做的更改将在cityName实例中更改MapDTO