javafx-properties is a library allowing to create JavaFX properties from JavaBeans. With it, any JavaBean can be used in a JavaFX application.
The library is companion to javafx.beans.property.adapter package.
It is inspired by the PresentationModel class from the JGoodies Binding library.
Get the library from Maven Central net.sf.mgp:javafx-properties
Start with a JavaBean:
public class Foo { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
Create a JavaFX property to observe the value changes:
Foo foo = new Foo(); JavaBeanProperty<String> valueProperty = NestedJavaBeanProperties.select(foo, "value");
This is it. valueProperty can be used by JavaFX.
valueProperty will have the value of foo.value. When valueProperty is updated, foo.value will be too automatically updated.
By the way. You do not even need setters for read-only properties. Create read-only properties like this:
ReadOnlyJavaBeanProperty<String> valueProperty = NestedJavaBeanProperties.selectReadOnly(foo, "value");
In the previous examples valueProperty will not be notified if the setValue() method is called. Add the usual JavaBean property notifications to change this:
public class Foo { private String value; public String getValue() { return value; } public void setValue(String value) { String old = this.value; this.value = value; pcs.firePropertyChange("value", old, this.value); } private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } }
Create a JavaFX property as before:
Foo foo = new Foo(); JavaBeanProperty<String> valueProperty = NestedJavaBeanProperties.select(foo, "value");
Now, when foo.value is updated, the value of valueProperty will be updated. Any javafx.beans.value.ChangeListener listening for valueProperty changes will be notified too.
Again, start with a JavaBean:
public class Foo { private Bar bar; public Bar getBar() { return bar; } public void setBar(Bar bar) { Bar old = this.bar; this.bar = bar; pcs.firePropertyChange("bar", old, this.bar); } private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } }
public class Bar { private String value; public String getValue() { return value; } public void setValue(String value) { String old = this.value; this.value = value; pcs.firePropertyChange("value", old, this.value); } private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } }
Now create a nested JavaFX property to observe the value property of the nested bean Bar:
Foo foo = new Foo(); JavaBeanProperty<String> valueProperty = NestedJavaBeanProperties.select(foo, "bar", "value");
The property value is now observed, although the value container (bean Bar) is not set.
Set the value and observe the property change:
Bar bar = new Bar(); foo.setBar(bar); bar.setValue("Hello, World!"); valueProperty.getValue(); // equals to "Hello, World!"
The setters are optional for the non-terminal properties (property bar of the bean Foo in this example). The property change notifications for the non-terminal properties are also optional. This means PropertyChangeSupport.firePropertyChange() or/and setBar() can be safely removed from the bean Foo.
If any nested property does not support JavaBean property change notifications, just call fireValueChangedEvent(). The property and all its containers (recursively, up to the property root) are refreshed.
valueProperty.fireValueChangedEvent();
Do not forget to dispose the property after use
valueProperty.dispose();
Also check the Frequently Asked Questions section.