Gregor28
(Gregor Dschung)
November 20, 2020, 2:07pm
1
I’m trying to refresh a TreeGrid in Vaadin 14 using treeGrid.setTreeData(newTreeData); treeGrid.getDataProvider().refreshAll();
.
This works fine, but unfortunately the grid’s nodes’ lose their collapse/expand states. I stronlgy guess this is the expected behaviour.
In order to keep the states I guess I must not reset the TreeData, but modify it. Therefore I need to determine the diff between two TreeData objects.
But before I start implementing a solution, am I missing something?
Kleanthis
(Kleanthis Mitsioulis)
December 16, 2020, 11:52am
2
I am having the same issue. I update an expanded parent’s children and then refresh the parent and the children. Unfortunately parent is collapsing after the refresh.I call expand on parent after refresh but nothing happens (calling isExpanded on parent returns true although parent is now collapsed in GUI)
Hi,
That might be related to this bug: https://github.com/vaadin/vaadin-grid/issues/1820 but it should be released in the Vaadin 14 (14.4.3+).
Which version of Vaadin 14 are your using?
Gregor28
(Gregor Dschung)
December 17, 2020, 4:21pm
4
I’ve used 14.4.2 and just updated to 14.4.4. But it seems to behave the same way as before:
if I set new TreeData with setTreeData(...)
, I still have to maintain the expanded nodes and call expand(expandedNodes)
after refreshing. expandedNodes is maintained with
treeGrid.addExpandListener(e -> expandedNodes.addAll(e.getItems()));
treeGrid.addCollapseListener(e -> expandedNodes.removeAll(e.getItems()));
it flickers
if I update the initial TreeData instance instead of using a new one, refreshAll()
keeps the states, but the TreeGrid flickers, too
Gregor28
(Gregor Dschung)
December 17, 2020, 4:28pm
5
This is my code to sync two TreeData instances, maybe it’s useful for someone else, too:
public class TreeDataSynchronizer {
<T> void sync(TreeData<T> from, TreeData<T> to) {
Queue<T> queue = new LinkedList<>();
queue.add(null); // root node
while (! queue.isEmpty()) {
T currentItem = queue.poll();
List<T> expectedChildren = from.getChildren(currentItem);
update(to, currentItem, expectedChildren);
queue.addAll(expectedChildren);
}
}
private <T> void update(TreeData<T> td, T parent, List<T> listOfExpectedChildren) {
Queue<T> expectedChildren = new LinkedList<>(listOfExpectedChildren);
Queue<T> currentChildren = new LinkedList<>(td.getChildren(parent));
while (!expectedChildren.isEmpty()) {
T expectedChild = expectedChildren.poll();
T currentChild = currentChildren.poll();
while (!Objects.equals(currentChild, expectedChild)) {
if (currentChild == null) {
td.addItem(parent, expectedChild);
break;
}
td.removeItem(currentChild);
currentChild = currentChildren.poll();
}
}
if (expectedChildren.isEmpty()) {
currentChildren.forEach(td::removeItem);
}
}
}
Tatu2
(Tatu Lund)
December 18, 2020, 5:58am
6
if I update the initial TreeData instance instead of using a new one, refreshAll() keeps the states, but the TreeGrid flickers, too
Yes, that is unfortunately true. You can see the same effect also with this live code example
https://cookbook.vaadin.com/treegrid-subtree-highlight
I added a ticket in our issue tracker about this https://github.com/vaadin/vaadin-grid/issues/2109