Community
Participate
Working Groups
Build ID: M20071023-1652 Steps To Reproduce: 1. Make a multiple selection (select several nodes) in your GEF editor 2. Click in one of the selected nodes 3. My application builds a ProgressBar to report the progress spent in a private task 4. NullPointerException is thrown More information: I get a NullPointerException in the method handleButtonUp, because getCurrentViewer() is null. I want to give the user some feedback about a task that's being performed, so to report the progress and allow the cancellation, I've used a ProgressMonitorDialog. This is the situation: when the user clicks a node in my editor I return some info about that node. This exception only happens when, after I select several nodes, I click in one of them... When I click in only one (without previous multiple selection), the progress bar and all the information are displayed. I believe the problem would be solved with a correction provided in 'org.eclipse.gef.tools.SelectEditPartTracker' class. There is 'null' check missing. Method 'handleButtonUp(int button)': protected boolean handleButtonUp(int button) { if (isInState(STATE_DRAG)) { performSelection(); if (getFlag(FLAG_ENABLE_DIRECT_EDIT)) performDirectEdit(); if (button == 1 && getSourceEditPart().getSelected() != EditPart.SELECTED_NONE) getCurrentViewer().reveal(getSourceEditPart()); <-- before this line there should be check: 'getCurrentViewer()!=null' setState(STATE_TERMINAL); return true; } return false; }
It's hard to guess what is happening without a stack trace, but it sounds like you've caused focus lost to occur while the mouse up event is still being processed. This sounds like a simple fix in GEF, but how defensive would we have to make the code in GEF for things like this? Do you really want to disable the canvas while the user is clicking on it? I suspect that is what has happened here. It sounds like you might benefit from something like a postSelection event, which doesn't exist yet in GEF, but does exist in some of the jface viewers. You could wait to do your job "later" by using an asyncExec when you see that selection has changed, so that the buttonUp has time to finish. Can you attach a stack trace and/or more info about what you mean by "builds a ProgressBar"?
I'm sorry for my late reply. Given the request for more information, here they are (I hope this helps): The exception is thrown from GEF plugin. The variable "currentViewer" is set to null in GEF. Stack trace: DragEditPartsTracker(SelectEditPartTracker).handleButtonUp(int) line: 115 > here getCurrentViewer() is null DragEditPartsTracker.handleButtonUp(int) line: 336 DragEditPartsTracker(AbstractTool).mouseUp(MouseEvent, EditPartViewer) line: 1053 PanningSelectionTool(SelectionTool).mouseUp(MouseEvent, EditPartViewer) line: 544 DefaultEditDomain(EditDomain).mouseUp(MouseEvent, EditPartViewer) line: 259 DomainEventDispatcher.dispatchMouseReleased(MouseEvent) line: 374 LightweightSystem$EventHandler.mouseUp(MouseEvent) line: 538 TypedListener.handleEvent(Event) line: 206 EventTable.sendEvent(Event) line: 66 FigureCanvas(Widget).sendEvent(Event) line: 938 Display.runDeferredEvents() line: 3682 Display.readAndDispatch() line: 3293 Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2389 Workbench.runUI() line: 2353 Workbench.access$4(Workbench) line: 2219 Workbench$4.run() line: 466 (…………) DragEditPartsTracker(AbstractTool).setViewer(EditPartViewer) line: 1325 > here currentViewer is set to null DragEditPartsTracker(AbstractTool).deactivate() line: 363 DragEditPartsTracker(TargetingTool).deactivate() line: 81 DragEditPartsTracker.deactivate() line: 207 PanningSelectionTool(SelectionTool).setDragTracker(DragTracker) line: 583 PanningSelectionTool(SelectionTool).handleFocusLost() line: 240 PanningSelectionTool.handleFocusLost() line: 139 PanningSelectionTool(AbstractTool).focusLost(FocusEvent, EditPartViewer) line: 423 DefaultEditDomain(EditDomain).focusLost(FocusEvent, EditPartViewer) line: 95 DomainEventDispatcher.dispatchFocusLost(FocusEvent) line: 232 LightweightSystem$EventHandler.focusLost(FocusEvent) line: 353 TypedListener.handleEvent(Event) line: 136 EventTable.sendEvent(Event) line: 66 FigureCanvas(Widget).sendEvent(Event) line: 938 FigureCanvas(Widget).sendEvent(int, Event, boolean) line: 962 FigureCanvas(Widget).sendEvent(int) line: 943 FigureCanvas(Control).sendFocusEvent(int) line: 2352 FigureCanvas(Widget).wmKillFocus(int, int, int) line: 1681 FigureCanvas(Control).WM_KILLFOCUS(int, int) line: 4000 FigureCanvas(Canvas).WM_KILLFOCUS(int, int) line: 337 FigureCanvas(Control).windowProc(int, int, int, int) line: 3703 FigureCanvas(Canvas).windowProc(int, int, int, int) line: 291 Display.windowProc(int, int, int, int) line: 4364 OS.BringWindowToTop(int) line: not available [native method] Shell(Decorations).bringToTop() line: 227 Shell.open() line: 1068 ProgressMonitorDialog(Window).open() line: 792 ProgressMonitorDialog.open() line: 664 ProgressMonitorDialog.aboutToRun() line: 567 ProgressMonitorDialog.run(boolean, boolean, IRunnableWithProgress) line: 492 ……..calculate()……. line: 47 (This code is mine) And this is the “my” exception: Caused by: java.lang.NullPointerException at org.eclipse.gef.tools.SelectEditPartTracker.handleButtonUp(SelectEditPartTracker.java:115) at org.eclipse.gef.tools.DragEditPartsTracker.handleButtonUp(DragEditPartsTracker.java:336) at org.eclipse.gef.tools.AbstractTool.mouseUp(AbstractTool.java:1053) at org.eclipse.gef.tools.SelectionTool.mouseUp(SelectionTool.java:544) at org.eclipse.gef.EditDomain.mouseUp(EditDomain.java:259) at org.eclipse.gef.ui.parts.DomainEventDispatcher.dispatchMouseReleased(DomainEventDispatcher.java:374) at org.eclipse.draw2d.LightweightSystem$EventHandler.mouseUp(LightweightSystem.java:538) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:206) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3682) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3293) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
I'm not sure I follow... is that one stack trace? Is mouseUp dispatched by SWT twice? Why does setViewer(null) cause the event loop to run? What caused the progress monitor dialog to open? Can you provide the whole trace, or at least the parts of it that involve eclipse code? The log file might get truncated, so you'll probably have to catch the exception in the debugger.
Hi, Randy. Indeed the log file didn't help much so I decided to give you a stack trace truncated (obtained with the debugger's help). I thought this would help... About your questions: Is mouseUp dispatched by SWT twice? --> Yes. Once when I select several nodes and after when I "pick" one in the group that I've selected before. Why does setViewer(null) cause the event loop to run? --> It doesn't... It seems that way because I've truncated the stack. Sorry... Once I select several nodes, currentViewer is set to null (setViewer(null)). Then inside that selection, I select one node. The progress monitor dialog is opened and the exception is caught. What caused the progress monitor dialog to open? --> I have in my code this method: private void calculateWithProgressBar() { ProgressMonitorDialog pd = new ProgressMonitorDialog(GuiHelper.getShell()); try { pd.run(true, true, new aRunnable(node)); } catch (Exception e) { } } where aRunnable implements IRunnableWithProgress (which belongs to the package org.eclipse.jface.operation). I don't know if the stack below helps you... It's the stack I've obtained with the debugger to catch the null exception (this isn't complete... after this, the exception is handled by the code inside my project): at org.eclipse.ui.internal.ExceptionHandler.handleException(ExceptionHandler.java:62) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2393) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219) at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at de.siemens.spt.application.Application.run(Application.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethod(EclipseAppContainer.java:572) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:171) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:447) at org.eclipse.equinox.launcher.Main.run(Main.java:1173) at org.eclipse.equinox.launcher.Main.main(Main.java:1148)