Search code examples
data-bindingjavafxunmodifiablelistproperty

How to make JavaFX ListProperty modifiable only through custom methods


I have a private list and I don't want that it can be modified from outside in general. Just adding from outside is allowed and only if the object is valid. Therefore I used to write it like this:

private List<Object> list = new ArrayList<>();

public List<Object> getList()
{
    return Collections.unmodifiableList(list);
}

public void addObject(Object object)
{
    if (isObjectValid(object)) //any validation
        list.add(object);
}

Now for JavaFX purposes I turn the list to a property:

private ListProperty<Object> list =
               new SimpleListProperty<>(FXCollections.observableArrayList());

To profit from the benefits of an property like data binding and the ListChangeListener I have to provide the property to the outer world. But then access to all methods of a list is provided, too. (To use a ReadOnlyListProperty has no effect since the list instance itself will never change.) What can I do to achieve all goals:

  • private ListProperty
  • ListChangeListener can be added from outside
  • Usable for binding dependencies from outside (the create methods form class Bindings)
  • No modifying of the property or list instance itself
  • Modifying of list content from outside only through my own methods

Solution

  • Not tested, but try:

    private ListProperty<Object> list = new SimpleListProperty<>(FXCollections.observableArrayList());
    
    private ReadOnlyListWrapper<Object> publicList = new ReadOnlyListWrapper<>();
    

    and in the constructor:

    publicList.bind(Bindings.createObjectBinding(
        () -> FXCollections.unmodifiableObservableList(list.getValue()),
        list));
    

    then your accessor method is

    public ReadOnlyListProperty<Object> getList() {
        return publicList.getReadOnlyProperty();
    }