Community
Participate
Working Groups
I tried calling refresh on treeviewer in treeExpanded function. The result is it mess up the tree, there is only one children without a label. Code to reproduce: public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); drillDownAdapter = new DrillDownAdapter(viewer); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setSorter(new NameSorter()); viewer.setInput(getViewSite()); viewer.addTreeListener(new ITreeViewerListener() { public void treeCollapsed(TreeExpansionEvent event) { } public void treeExpanded(TreeExpansionEvent event) { viewer.refresh(event.getElement()); }}); }
Created attachment 24711 [details] the test case to reproduce this bug
workaround is doing this: viewer.getControl().getDisplay().asyncExec(new Runnable() { public void run() { viewer.refresh(byUserId); } });
(In reply to comment #2) Have seen this problem when objects are added to the model, this workaround also forces the treeviewer to redraw properly: viewer.refresh(true); Object[] objs = viewer.getExpandedElements(); viewer.expandAll(); viewer.collapseAll(); viewer.setExpandedElements(objs);
This bug has been open for quite a while, and while it does have a workaround, it still causes considerable confusion. I just ran into it while learning how to use ITreeViewerListener, and it took two or three hours of trying different things before I found this issue and thus the workaround. Perhaps it could be looked into and resolved properly? The good news is that the workarounds do work, with apparently little negative impact. I'm using the variant that Michael posted above, but I found the 'byUserId' variable he used in as an argument to refresh() to be confusing. Here's another snippet that should be more context-complete and general purpose for those freshly running into this problem: new ITreeViewerListener() { public void treeExpanded(final TreeExpansionEvent event) { // add items to the node, do whatever you need to do, e.g.: MyTreeNode node = (MyTreeNode) event.getElement(); node.addChild(new MyTreeNode("foo"); // execute the workaround that refreshes the newly updated node viewer.getControl().getDisplay().asyncExec(new Runnable() { public void run() { viewer.refresh(event.getElement()); } }); } };
TreeViewer is not designed to allow recursive back-calls like this one. I've released code that checks for this and logs a warning. The snippet from comment #4 is the recommended workaround.
Verified that the log entry is produced when expanding an item in the attached view. I20070918-0010.