I have developed some code and I have a Set
of User
s:
public class ParkCentral{
private Set<User> users = new HashSet<>();
}
Then, in a different class, I'm developing a GUI and a TableView of User
s.
The problem is that I can't create a ObervableList
from a Set
. And I would like that changes on ParkCentral.users
would be reflected on TableView.
It is possible do this without changing ParkCentral
implementation, without changing the Set
to List
?
Why TableView only works with ObservableList and not with ObservableSet or ObservableMap?
Why TableView only works with ObservableList and not with ObservableSet or ObservableMap?
A TableView
presents an ordered collection of items. Neither Map
nor Set
fulfill those requirements (except for some implementations).
It's possible to listen to changes in the Set
and make appropriate changes in the List
though. This is not possible with just a HashSet
though; there's simply no way to observe this collection; you'd always need to manually update the list after changes have been made.
Using a ObservableSet
instead allows you to add a listener that does updates to a list though.
public class SetContentBinding<T> {
private final ObservableSet<T> source;
private final Collection<? super T> target;
private final SetChangeListener<T> listener;
public SetContentBinding(ObservableSet<T> source, Collection<? super T> target) {
if (source == null || target == null) {
throw new IllegalArgumentException();
}
this.source = source;
this.target = target;
target.clear();
target.addAll(source);
this.listener = c -> {
if (c.wasAdded()) {
target.add(c.getElementAdded());
} else {
target.remove(c.getElementRemoved());
}
};
source.addListener(this.listener);
}
/**
* dispose the binding
*/
public void unbind() {
source.removeListener(listener);
}
}
Usage example:
public class ParkCentral{
private ObservableSet<User> users = FXCollections.observableSet(new HashSet<>());
}
new SetContentBinding(parkCentral.getUsers(), tableView.getItems());