I get data in the format of an ObservableMap<T, Foo>
.
To implement this data in a View I need the values of that map in the format of an ObservableList<Foo>
.
Because I need the data in a Map Collection (to avoid duplicates and other reasons) I was wondering if it is possible to bind these 2 collections.
Something like:
ObservableMap<Integer, Foo> data = FXCollections.observableHashMap();
ObservableList<Foo> target = FXCollections.observableArrayList();
// Won't work
Bindings.bindContent(target, data.values());
Binding because the data can change during runtime.
Edit: Initializing the List with map values is not working because the there will be addtional Foo's added to the map: Example with a String as map value:
ObservableMap<Integer, String> map = FXCollections.observableHashMap();
map.put(1, "a");
map.put(2, "b");
ObservableList<String> list = FXCollections.observableArrayList(map.value());
//map = {1=a, 2=b}
//list = [a, b]
// ok
map.put(3, "c");
//map = {1=a, 2=b, 3=c}
//list = [a, b]
// no update
from ObservableMap to ObservableList
ObservableMap<Integer, Foo> data = FXCollections.observableHashMap();
ObservableList<Foo> target = FXCollections.observableArrayList(data.values());
I have not found a built in solution in Java. I use a simple MapChangeListener when the Map is the source of the data, and the List is only for tracking changes to the Map value list.
ObservableMap<String, String> map = FXCollections.observableHashMap();
ObservableList<String> list = FXCollections.observableArrayList();
MapChangeListener<String, String> listener = c -> {
if (c.wasRemoved()) {
list.remove(c.getValueRemoved());
}
if (c.wasAdded()) {
list.add(c.getValueAdded());
}
};
map.addListener(listener);
map.put("1", "A");
map.put("2", "B");
map.put("1", "A'");
assertThat(list).containsExactlyInAnyOrder("A'", "B");
You should keep the observable list private, and only expose a unmodifiableObservableList externally, to prevent accidently adding list entries that are not in the map.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With