Community
Participate
Working Groups
getSelectionWithoutDependants() throws a NPE because the viewer parameter is null. The underlying problem is as follows: 1. In AbstractTool.mouseDown(), the current viewer is set in a field. 2. From mouseDown(), handleButtonDown() is called. The implementation is in SelectEditPartTracker, a subclass of AbstractTool. 3. handleButtonDown() calls select() on the viewer, which triggers workbench selection change notifications. 4. In the particular case that I encounter, we have a view listening for workbench selection change notifications that must invoke a IRunnableWithProgress in the context of a workbench window. This removes the focus from the edit part and then restores it. However, this leaves the SelectEditPartTracker with no viewer set. Here is the stack trace: java.lang.NullPointerException at java.lang.Throwable.<init>(Throwable.java) at java.lang.Throwable.<init>(Throwable.java) at java.lang.NullPointerException.<init>(NullPointerException.java:60) at org.eclipse.gef.tools.ToolUtilities.getSelectionWithoutDependants (ToolUtilities.java:29) at org.eclipse.gef.tools.DragEditPartsTracker.createOperationSet (DragEditPartsTracker.java:150) at org.eclipse.gef.tools.AbstractTool.getOperationSet (AbstractTool.java:575) at org.eclipse.gef.tools.DragEditPartsTracker.captureSourceDimensions (DragEditPartsTracker.java:108) at org.eclipse.gef.tools.DragEditPartsTracker.setState (DragEditPartsTracker.java:516) at org.eclipse.gef.tools.AbstractTool.stateTransition (AbstractTool.java:1260) at org.eclipse.gef.tools.SelectEditPartTracker.handleButtonDown (SelectEditPartTracker.java:93) at org.eclipse.gef.tools.AbstractTool.mouseDown(AbstractTool.java:974) at org.eclipse.gef.tools.SelectionTool.mouseDown (SelectionTool.java:481) at org.eclipse.gef.EditDomain.mouseDown(EditDomain.java:194) at org.eclipse.gef.ui.parts.DomainEventDispatcher.dispatchMousePressed (DomainEventDispatcher.java:314) at org.eclipse.draw2d.LightweightSystem$EventHandler.mouseDown (LightweightSystem.java:491) at org.eclipse.swt.widgets.TypedListener.handleEvent (TypedListener.java:132) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1353) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1324) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench (Workbench.java:243) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:141) at org.eclipse.ui.internal.ide.IDEApplication.run (IDEApplication.java:90) at org.eclipse.core.internal.runtime.PlatformActivator$1.run (PlatformActivator.java:298) at org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:249) at org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:126) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:84) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:59) at java.lang.reflect.Method.invoke(Method.java:390) at org.eclipse.core.launcher.Main.basicRun(Main.java:269) at org.eclipse.core.launcher.Main.run(Main.java:722) at org.eclipse.core.launcher.Main.main(Main.java:706)
I tagged this bug with the wrong GEF version. It should have been 3.0. Specifically, I tested it against the I20040619 GEF build on top of Eclipse 3.0 RC3.
Created attachment 12571 [details] Test case I attach a simple test case that illustrates this problem. It requires the GEF logic example (I used I20040619). The testcase plugin contributes a new view that registers a selection listener on the workbench window's selection service. Inside this listener, it invokes an IRunnableWithProgress that does nothing. STEPS TO REPRODUCE: 1. Create a new GEF logic 4 bit adder model example. 2. Open the testcase view (Window -> Show View -> Other... -> Sample Category -> Sample View). 3. Click on an element in the logic diagram. 4. Look at the Eclipse log file for the NPE.
See bug 65985.
Please try to reproduce using the RC2 version of the Platform.
I reproduced the test case from comment #2 using Eclipse 3.0 RC2 and GEF I20040619.
Thanks, I will investigate with the testcase.
I don't see anything we can do here. At first I was thinking that the tool should be in its TERMINAL state because it was deactivated when focus was lost. But doing that won't help you because then you will never be able to drag anything with the mouse. What is it you want to happen? Do you want the hourglass cursor when you select something? The selection tool unloads any drag tracker when focus lost occurs. The canvas should not lose focus during a mouse drag, if it does, the drag is aborted. So we could avoid the NPE, but then you could not drag.
Can you use fork==TRUE so that the UI is not temporarily disabled? This will avoid the focusLost event. I'm guessing that this is what the Problems/Tasks views do.
We can't call call run() with the fork==true because the call is made when creating a new editor in AbstractTextEditor.internalInit(), which we can't change or override. Our current workaround is to check if the active tool has a drag tracker (using reflection to access the private getDragTracker() method) and if it does then we cache it. Then, after the runnable has finished, we call setViewer() on the cached drag tracker tool to restore the correct viewer. We will keep on using our workaround since a solution at the GEF level doesn't seem reasonable. Thanks for your help in taking a look at this.
Why don't you build a delay into your selection listener similar to Windows Explorer. In other words, invoke a Display.timerExec(opensEditor, 500). If selection changes before then, cancel that runnable and start a new one. There are lots of cases where you will receive several selection events in rapid succession and it makes sense to only react to the last one.
Actually, we will fix this but it isn't the desired fix you are after, and may even break your workaround.
On windows, a native Tree or Table shows selection on mousedown, but *fires* notification on mouse up. But if you drag the mouse the widgets fire selection sooner. So if we emulate this behavior you would still have problems once the mouse starts dragging, and it may break clients. Steve, is there some way we could identify and ignore the spurious focusLost event? It seems that in this scenario focus is guaranteed to return to the control which had it (unless setFocus or dispose occurs?)
Not really, if focus is actually lost, then we can't (shouldn't) try to fake that it didn't or other things might break. Can you create a simple SWT only test case and log a problem report? Thanks.
AT: org.eclipse.gef.tools.SelectEditPartTracker.handleButtonDown (SelectEditPartTracker.java:93) The drag tracker has been deactivated at this point, but is still attempting to do more processing of the mouseDown because it is still in STATE_INITIAL. The fix is to add setState(STATE_TERMINAL) to AbstractTool#deactivate(). This way, any tool which has been deactivated will not continue to do stuff if it correctly checks its current state.
*** Bug 70607 has been marked as a duplicate of this bug. ***