如何在不使用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之间的字符串绑定?

最佳答案

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


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


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

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


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


所以我们遵守要求。

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

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


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

cityNameProperty.bind(cityNameTF.textProperty());


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

09-11 02:27
查看更多