jeudi 20 juin 2013

ListProperty vs ObjectProperty

In the world of JavaFX, when you need to use an ObservableList with the Property pattern, you write the following :


To be notified when the list content is modified, you can register a ListChangeListener on the ObservableList referenced by the ObjectProperty using the getter.
You can also register a ChangeListener on the ObjectProperty to be notified when the instance of ObservableList referenced by the ObjectProperty is modified.

You will end up with something like that :

  • If you add an element or more, your ListChangeListener will be notified.
  • If you change your ObservableList instance, your ChangeListener will be called.
But if the ObservableList instance referenced by the ObjectProperty has changed, and you try to add some elements to the new list instance, you won't be notified. This is because your ListChangeListener  is still registered on the previous ObservableList instance. So in your ChangeListener you have to unregister your ListChangeListener from the old ObservableList instance and register it to the new one. It's a little bit boring to do each time...

A major issue we discovered, is that if you replace an empty ObservableList by an other empty ObservableList, the ChangeListener is not notified, as we can see on this unit test, so that you can't correctly re-register the ListChangeListener on the new instance:

Why ? cause the equals method implementation return true between the two ObservableList.

So as you see... using an ObservableList with the Property pattern, is not really cool.

This is a problem, isn't it ??

Oh Legolas wants to help us. So listen what he says:

Replace our ObjectProperty<ObservableList<T> by a ListProperty<T>. ListProperty implements both Property<ObservableList> and ObservableList and makes the whole wrapping really transparent for the developer, taking care of the previous ListChangeListener manipulation automatically !
With that, if you want to be notified when the content of the List is modified, you just need to register the ListChangeListener once.

Like that :

When you do this, adding an element will notify the listener, and changing the ObservableList instance will call the listener to. And if you add an element after changing the list instance, no problem! the listener will also be notified of the change in the new list instance. No need to register a new Listener on the new List, the ListProperty manages it for you !

This unit test show us the ListChangeListener is called 5 times, once on each change.

Now you are ready to replace your ObjectProperty<ObservableList> by ListProperty ! Have fun

1 commentaire:

  1. Hi, How can I listen when a property of some element changes? ListChangeListener works only when I add / remove items from the list, but does not listen if I update one of them. Could you help me?