How can I bind ObjectProperty
's attribute (that itself is not a property) to some other property like a TextField
's text property without using a ChangeListener
?
More specifically:
I would like to make a TextField
change an ObjectProperty
's attribute.
Sample code:
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()));
}
}
I have tried:
Creating a string property from the selected value String attribute but it did not pan out & I wasn't able to find the right way.
cityNameTF.textProperty().bindBidirectional(Bindings.createStringBinding(
() -> selectMapCB.getValue() == null ? null : selectMapCB.getValue().getCityName(),
selectMapCB.valueProperty()));
Creating a string property from the mapProperty's String attribute.
cityNameTF.textProperty().bindBidirectional(Bindings.createStringBinding(
() -> MapsManager.getMapProperty().getValue() == null ? null : MapsManager.mapProperty().getValue().getCityName(),
MapsManager.mapProperty()));
Both options give the same error:
bindBidirectional (javafx.beans.property.Property<java.lang.String>)
in StringProperty cannot be applied to (javafx.beans.binding.StringBinding)
In both cases replacing bindBidirectional
with bind
works but then I can't change the text in the TextField
. I realized this is because I am binding the TextField
's text to the cityName
's String. So I thought of binding it one way but in the opposite direction, something like:
MapsManager.mapProperty().????.bind(cityNameTF.textProperty());
But "????" - I don't have a property for the String and I don't know how to create a StringBinding
or StringProperty
on the fly if that's even possible.
Your MapDTO
is basically a JavaBean - a class with a field and its getter and setter. We'll call such a field a bean property . Since you can't bind to or from these properties, JavaFX provides adapters that bridge them to JavaFX properties. They are located in the package javafx.beans.property.adapter :
Provides various classes that act as adapters between a regular Java Bean property and a corresponding JavaFX Property.
Internally, they function as wrappers of the bean property.
Since your MapDTO
contains a String
we'll use a JavaBeanStringProperty . Note that:
As a minimum, the Java Bean class must implement a getter and a setter for the property. The class, as well as the getter and a setter methods, must be declared public.
so we obey the requirements.
We create these adapter with their builders, JavaBeanStringPropertyBuilder in this case:
JavaBeanStringProperty cityNameProperty = JavaBeanStringPropertyBuilder.create()
.bean(MapsManager.getMap())
.name("cityName")
.build();
The builders access the data reflectively. Now we can use the created property as usual:
cityNameProperty.bind(cityNameTF.textProperty());
and changes to the text field's text
property will change cityName
in the MapDTO
instance.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.