Project: SWT
Bug 422090 Adding/Removing SWT.MeasureEvent listener will show tree without horizontal scrollbar
Reported: 2013-11-19 15:45:05 | Status: verified fixed

Issue: ------ Adding and then removing listener for SWT.MeasureEvent type from tree results in horizontal scrollbar getting removed. Because of adding/removing of listener as mentioned above, it is not able to trigger sendMeasureItemEvent() from the Tree widget code as the hook check for the event returns false. Below is code from SWT org.eclipse.swt.widgets.Tree.java for the same, if (hooks (SWT.MeasureItem)) { measureEvent = sendMeasureItemEvent (item, index, hDC, selected ? SWT.SELECTED : 0); if (isDisposed () || item.isDisposed ()) return null; } Scenario: --------- This behavior creates problem when using org.eclipse.ui.navigator.CommonViewer.java with custom label provider. As while creating the instance of CommonViewer, it will use default label provider for it and listener is attached for SWT.MeasureEven in this flow. Below is the call trace of the method which adds listener while creating CommonViewer instance, OwnerDrawLabelProvider.getOrCreateOwnerDrawListener(ColumnViewer) line: 93 NavigatorDecoratingLabelProvider(OwnerDrawLabelProvider).setOwnerDrawEnabled(ColumnViewer, ViewerColumn, boolean) line: 250 NavigatorDecoratingLabelProvider(OwnerDrawLabelProvider).initialize(ColumnViewer, ViewerColumn, boolean) line: 156 NavigatorDecoratingLabelProvider(StyledCellLabelProvider).initialize(ColumnViewer, ViewerColumn) line: 165 NavigatorDecoratingLabelProvider.initialize(ColumnViewer, ViewerColumn) line: 173 CommonViewer(ColumnViewer).setLabelProvider(IBaseLabelProvider) line: 367 CommonViewer.init() line: 110 CommonViewer.<init>(String, Composite, int) line: 97 When the label provider for CommonViewer is changed in application code it triggers code which removes the listener attached in above flow. Work Around: ------------ Adding a dummy listener to tree for SWT.MeasureEvent in application will resolve the issue. commonViewer.getTree().addListener(SWT.MeasureItem, new Listener() { @Override public void handleEvent(Event event) { } }); Sample code to reproduce: -------------------------- public class NoHScrollbar { public static void main(String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout (new FillLayout()); final Tree tree= new Tree(shell, SWT.NONE); for (int i= 0; i < 25; i++) { TreeItem item= new TreeItem(tree, SWT.NONE); item.setText("Tree Item at index " + i); } Listener listener = new Listener() { public void handleEvent(Event e) { } }; tree.addListener(SWT.MeasureItem, listener); tree.removeListener(SWT.MeasureItem, listener); /* Work around: Adding listener again will resolve the issue. Removing comment below will show horizontal scrollbar. */ // tree.addListener(SWT.MeasureItem, listener); shell.setSize(50, 500); shell.open(); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } }

Files changed in fix:
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java