Community
Participate
Working Groups
When the ILazyTreePathContentProvider.updateElement() is called, the content provider needs to call TreeViewer.replace() and TreeViewer.setChildCount() to refresh the element's state. However, if the old element at the same index was previously expanded, the setHasChildren() has no effect. This is because a test in TreeViewer.setHasChildren() causes the update to be inored if the item is already expanded. Adding a call to update the child count for the node seems to fix the problem (patch to be attached). Use sample below to reproduce the problem: 1) Expand the first item. 2) Press the "Change Order" button. 3) Expand second item. 4) Press the "Change Order" button again. Problem: The '+' disappears from the second item. public class TestJFace { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display, SWT.SHELL_TRIM); shell.setLayout(new GridLayout()); GridData data = new GridData(GridData.FILL_BOTH); shell.setLayoutData(data); Font font = new Font(display, "Courier", 10, SWT.NORMAL); final TreeViewer treeViewer = new TreeViewer(shell, SWT.VIRTUAL | SWT.BORDER); treeViewer.getControl().setLayoutData(data); final ContentProvider contentProvider = new ContentProvider(treeViewer); treeViewer.setContentProvider(contentProvider); treeViewer.setInput(new Object()); Button button = new Button(shell, SWT.NONE); button.setText("Change Order"); button.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) {} public void widgetSelected(SelectionEvent e) { fgParentFirst = !fgParentFirst; treeViewer.refresh(); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } font.dispose(); } public static boolean fgParentFirst = true; public static class ContentProvider implements ILazyTreePathContentProvider { TreeViewer fViewer; ContentProvider(TreeViewer viewer) { fViewer = viewer; } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } public void updateHasChildren(TreePath path) { if (path.getSegmentCount() == 0) { fViewer.setHasChildren(path, true); } else if (path.getSegmentCount() == 1) { if ("Parent".equals(path.getSegment(0))) { fViewer.setHasChildren(path, true); } else { fViewer.setHasChildren(path, false); } } else { fViewer.setHasChildren(path, false); } } public void updateChildCount(TreePath path, int currentChildCount) { if (path.getSegmentCount() == 0) { fViewer.setChildCount(path, 2); } else if (path.getSegmentCount() == 1) { if ("Parent".equals(path.getSegment(0))) { fViewer.setChildCount(path, 1); } else { fViewer.setChildCount(path, 0); } } else { fViewer.setChildCount(path, 0); } } public void updateElement(TreePath path, int index) { Object object = null; if (path.getSegmentCount() == 0) { if (index == 0) { object = fgParentFirst ? "Parent" : "Non-Parent"; } else if (index == 1) { object = fgParentFirst ? "Non-Parent" : "Parent"; } } else if (path.getSegmentCount() == 1) { if ("Parent".equals(path.getSegment(0))) { object = "Child"; } } if (object != null) { fViewer.replace(path, index, object); updateHasChildren(path.createChildPath(object)); } } public TreePath[] getParents(Object element) { return new TreePath[0]; } public void dispose() {} } }
Created attachment 58621 [details] Patch to request children count update if node is expanded upon setHasChildren().
*** Bug 173898 has been marked as a duplicate of this bug. ***
Marking as major, as this impacts the usability of the variables view.
Released >20070316. Thanks for the patch, and sorry for not releasing this earlier.
Verified in I20070322-1800 - thanks for the excellent test case
thanks :-)