Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 313424

Summary: NPE in Control.invalidateVisibleRegion when expanding/collapsing tree node
Product: [Eclipse Project] Platform Reporter: Nick Edgar <n.a.edgar>
Component: SWTAssignee: Silenio Quarti <Silenio_Quarti>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: gheorghe, Silenio_Quarti, skovatch
Version: 3.6Flags: skovatch: review+
gheorghe: review+
Target Milestone: 3.6 RC2   
Hardware: PC   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:
Attachments:
Description Flags
fix none

Description Nick Edgar CLA 2010-05-18 15:03:21 EDT
3.6 M7 - Cocoa - 32-bit

In RTC,
- select a change set in the Pending Changes view (uses an owner-draw Tree)
- hit F2 to open the edit field (a child text field)
- click the expand/collapse triangle for the change set
- it fails with:

java.lang.NullPointerException
at org.eclipse.swt.widgets.Control.invalidateVisibleRegion(Control.java:1891)
at org.eclipse.swt.widgets.Control.setVisible(Control.java:3743)
at org.eclipse.swt.custom.TreeEditor$3.treeCollapsed(TreeEditor.java:117)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:104)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3734)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1335)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1358)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1343)
at org.eclipse.swt.widgets.TreeItem.sendExpand(TreeItem.java:1018)
at org.eclipse.swt.widgets.Tree.collapseItem_collapseChildren(Tree.java:425)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5133)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:221)
at org.eclipse.swt.widgets.Widget.mouseDownSuper(Widget.java:993)
at org.eclipse.swt.widgets.Tree.mouseDownSuper(Tree.java:1957)
at org.eclipse.swt.widgets.Widget.mouseDown(Widget.java:989)
at org.eclipse.swt.widgets.Control.mouseDown(Control.java:2222)
at org.eclipse.swt.widgets.Tree.mouseDown(Tree.java:1934)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:4928)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:221)
at org.eclipse.swt.widgets.Widget.windowSendEvent(Widget.java:1911)
at org.eclipse.swt.widgets.Shell.windowSendEvent(Shell.java:1998)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:4992)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Display.applicationSendEvent(Display.java:4536)
at org.eclipse.swt.widgets.Display.applicationProc(Display.java:4613)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
at org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSApplication.java:115)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3247)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2601)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2565)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2399)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:669)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:662)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
at org.eclipse.equinox.launcher.Main.run(Main.java:1407)


Silenio says:
"The parent slot of the control (editor) is null. I am not sure how this can happen. The parent slot should only be null when the widget is disposed, but setVisible() should have thrown a widget disposed exception if that was the case."
Comment 1 Scott Kovatch CLA 2010-05-18 16:02:58 EDT
Do I need RTC to reproduce this or will a straight 3.6 work?
Comment 2 Silenio Quarti CLA 2010-05-18 17:49:41 EDT
This testcase reproduces the problem. The editor is disposed when it looses focus after calling NSView.setHidden().

import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;


public class PR313424 {
public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setLayout(new GridLayout(1, false));

	final Tree tree = new Tree(shell, SWT.BORDER);
	for (int i = 0; i < 3; i++) {
		TreeItem item = new TreeItem(tree, SWT.NONE);
		item.setText("item " + i);
		for (int j = 0; j < 3; j++) {
			TreeItem subItem = new TreeItem(item, SWT.NONE);
			subItem.setText("item " + i + " " + j);
		}
	}
	
	final TreeEditor editor = new TreeEditor(tree);
	//The editor must have the same size as the cell and must
	//not be any smaller than 50 pixels.
	editor.horizontalAlignment = SWT.LEFT;
	editor.grabHorizontal = true;
	editor.minimumWidth = 50;
	
	tree.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
			// Clean up any previous editor control
			Control oldEditor = editor.getEditor();
			if (oldEditor != null) oldEditor.dispose();
	
			// Identify the selected row
			TreeItem item = (TreeItem)e.item;
			if (item == null) return;
	
			// The control that will be the editor must be a child of the Tree
			final Text newEditor = new Text(tree, SWT.NONE);
			newEditor.setText(item.getText());
			newEditor.addModifyListener(new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					Text text = (Text)editor.getEditor();
					editor.getItem().setText(text.getText());
				}
			});
			newEditor.addListener(SWT.FocusOut, new Listener() {
				public void handleEvent(Event event) {
					newEditor.dispose();
				}
			});
			newEditor.selectAll();
			newEditor.setFocus();
			editor.setEditor(newEditor, item);
		}
	});

	shell.pack();
	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch())
			display.sleep();
	}
	display.dispose();
}
}
Comment 3 Silenio Quarti CLA 2010-05-18 17:51:14 EDT
Created attachment 169030 [details]
fix
Comment 4 Silenio Quarti CLA 2010-05-19 10:54:42 EDT
Fixed > 20100518 (build I20100519-0839 should have it)