Is there support for listening to changes in observables of the ObservableList items?
Adito5393 opened this issue · comments
Great work on keeping the library alive and providing the JMPS support! đź‘Ť
The javafx offers the following implementation that does exacly this:
public static <E> ObservableList<E> observableArrayList​(Callback<E,​Observable[]> extractor)
(see the javadocs)
The problem I have is that I have an ObservableList
of TreeItems
of my customClass
that I would love to convert to an ObservableList.
I tried using EasyBind.map
, however now the changes to the underlying data are not triggering the events changes (only the properies changes).
The good part is that when I add or remove items, the lists are in sync,
Using the extractor
callback that looks something like this:
ObservableList<customClass> tasksList = FXCollections.observableArrayList(param -> new Observable[] {param.nameProperty()});
The UI gets the changes updates, minus the addition or subtraction of the items to the underlying list.
Can I use somehow EasyBind
and pass a Callback<E,​Observable[]> extractor
?
So what you want is that if a change to one of the items in the original list triggers an update of the mapped list as well?
This should be possible by providing the extractor on the original list as in the following code snippet
var list = FXCollections.observableArrayList(param -> extractor logic here);
// Fill list etc
var mapped = EasyBind.map(list);
Now mapped
should be updated if items in list
are changed.
If that doesn't work, could you please provide a simple code example - in the best case as a failing unit test.
Correct!
Unfortunately, I can not modify the way the observableArrayList is created (can't attach the extractor logic at initialization time) because I obtain it from the TreeItem
method getChildren()
.
I tried using 2 methods from EasyBind: EasyBind.map
and EasyBind.flatten
:
Here is the code I used that does not trigger changes to the underlying properties changes:
// finalTasksList is needed to combine all lists available under Root TreeItem: esmCore
ObservableList<ObservableList<? extends EsmRowJFX>> finalTasksList =
FXCollections.observableArrayList();
getRoot().getChildren().forEach(esmCore -> {
ObservableList<TreeItem<EsmRowJFX>> treeItemTasks = esmCore.getChildren();
ObservableList<EsmRowJFX> tasksList = EasyBind.map(treeItemTasks,TreeItem::getValue); //TreeItem::getValue is NOT the extractor logic code!
// I tried EasyBind.mapBacked instead of EasyBind.map and the result behavior is the same!
finalTasksList.add(tasksList);
});
ObservableList<EsmRowJFX> list = EasyBind.flatten(finalTasksList);
setAllTasks(list); // set the list to the Class property: ObjectProperty<ObservableList<EsmRowJFX>>
I could attempt to write a unit test to generalize the example, if you think this type of feature can be implemented within EasyBind ?!
Could you point me to a unit test example that could speed up my process?
If treeItemTasks
doesn't raise a change event when one of the items in this list is changed then there there is nothing we can do on the side of EasyBind. I'm not that familiar with TreeItem, but I guess you can inherit from it and overwrite the getChildren
method to return a list with the proper extractor.
You are right!
Extending the TreeItem would be quite complex since I will have to overwrite the private ObservableList<TreeItem<T>> children
and also overwrite all the private methods that used that children
member.
I will close the issue. Thanks for your feedback!