This discussion is archived
2 Replies Latest reply: Jan 24, 2013 7:03 PM by bouye RSS

An elegant way to listen for changes in any property of a property?

Andipa Newbie
Currently Being Moderated
Is there one?

I have a generic ObjectProperty and would like to have any change to a property in the ObjectProperty's value object trigger a notification on the ObjectProperty having changed.

An example:
public class PropertyBindingTest {

    public static void main(String[] args) {
        ObjectProperty<Dimension> dimensionObjectProperty = new SimpleObjectProperty<>();
        ObjectPropertyChangePrinter.add(dimensionObjectProperty);

        Dimension dimension = new Dimension(1, 1);
        dimensionObjectProperty.setValue(dimension);
        dimension.x.set(3);
        dimensionObjectProperty.setValue(new Dimension(5, 1));
    }

    static class ObjectPropertyChangePrinter {
        public static <T> void add(ObjectProperty<T> objectProperty) {
            objectProperty.addListener(new ChangeListener<T>() {
                @Override
                public void changed(ObservableValue<? extends T> observableValue, T t, T t1) {
                    System.out.println(t1);
                }
            });
        };
    }

    static class Dimension {
        DoubleProperty x = new SimpleDoubleProperty();
        DoubleProperty y = new SimpleDoubleProperty();

        Dimension(double x, double y) {
            this.x.set(x);
            this.y.set(y);
        }

        @Override
        public String toString() {
            return x + "," + y;
        }
    }

}
In this example, I would like the dimension.x.set(3) to trigger the change listener, the code should be independent from whatever object is put inside as long as it does specifies its attributes as properties.
The only way I can think of accomplishing that is using Reflection to iterate over all Property attributes of the object. But maybe there is a more elegant JavaFX built-in approach?
  • 1. Re: An elegant way to listen for changes in any property of a property?
    James_D Guru
    Currently Being Moderated
    It's not exactly the same, but ObservableLists can report changes to properties in the elements of the list if you specify an "extractor" for them. The mechanism they use is that you create an ObservableList<T> and specify a Callback<T, Observable[]) which returns an array of properties to be observed for each item in the list. You could try to emulate this for ObjectProperty<T>.

    See the javadocs at http://docs.oracle.com/javafx/2/api/javafx/collections/FXCollections.html#observableList(java.util.List, javafx.util.Callback) which contains a (very) brief description. [Note the part in parentheses is part of the link, the forum formatting will likely remove these so you may need to copy and paste into the browser to get the link to the correct anchor in the page.]

    There are some subtleties in implementing this. Obviously you register listeners with the properties the extractor returns, but if set(...) is called on the "outer" object property, you need to remove those listeners and register them with the new value.
  • 2. Re: An elegant way to listen for changes in any property of a property?
    bouye Journeyer
    Currently Being Moderated
    You can do something similar to what I do in this code:
    saveItem.disableProperty().bind(Bindings.selectBoolean(editorProperty(), "canSave").not()); // NOI18N.
    where canSave is a BooleanProperty in the Editor class contained in the editor property.
    And then set a listener on the BooleanBinding that is returned by selectBoolean().

    Edited by: bouye on Jan 25, 2013 1:03 PM

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points