Project: Eclipse_Platform_UI
Bug 364402 NPE in MinMaxAddon with non-visible editor area
Reported: 2011-11-21 13:16:22 | Status: verified fixed

BuildId: I20111028-1100 I'm fiddling with an app that uses the compatibility layer that defines a custom perspective where the editor area is set to be not visible. When running with the org.eclipse.e4.ui.swt.addons bundle, I double-clicked on a view tab that ultimately triggered an NPE in MinMaxAddon#createTrim(). The problem arises as: 1. MinMaxAddon's CTFDblClickListener#mouseDoubleClickListener marks the tab control to be maximized, 2. This causes the part stack to have a new MAXIMIZED tag item. 3. This triggers MinMaxAddon's #tagChangeListener's handleEvent to try to maximize the part stack 4. The end of MinMaxAddon#maximize() fetches the editor area placeholder and adds a MINIMIZED tag. 5. This then triggers the MinMaxAddon's #tagChangeListener's handleEvent on the editor area MPlaceholder 6. This handler calls MinMaxAddon#minimize() on the MPlaceholder, which attempts to create trim for the placeholder. 7. MinMaxAddOn#createTrim() fetches bounds of the element's widget, which does not exist as it's not rendered: private void createTrim(MUIElement element) { ... Control stackCtrl = (Control) element.getWidget(); Rectangle stackBounds = stackCtrl.getBounds(); // NPE My guess is that MinMaxAddon#minimize() and maximize() should have is-rendered guards for the provided element? Stack values at MinMaxAddon#createTrim(): ----------------------- this = MinMaxAddon element = org.eclipse.e4.ui.model.application.ui.advanced.impl.PlaceholderImpl@486985a3 (elementId: org.eclipse.ui.editorss, tags: [MinimizedByZoom, Minimized], contributorURI: null) (widget: null, renderer: null, toBeRendered: false, onTop: false, visible: true, containerData: 6000, accessibilityPhrase: null) (closeable: false) window = org.eclipse.e4.ui.model.application.ui.basic.impl.TrimmedWindowImpl@32e6e42e (elementId: IDEWindow, tags: [topLevel], contributorURI: platform:/plugin/org.eclipse.ui.workbench) (widget: Shell {Eclipse SDK 4.0}, renderer: org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer@157dd1d1, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: Eclipse SDK 4.0, iconURI: null, tooltip: null, context: TrimmedWindowImpl (IDEWindow) Context, variables: [], x: 79, y: 32, width: 1024, height: 768) winShell = a shell trimId = org.eclipse.ui.editorss(app.perspective) trimStack = org.eclipse.e4.ui.model.application.ui.menu.impl.ToolControlImpl@5382ab40 (elementId: org.eclipse.ui.editorss(px.perspective), tags: null, contributorURI: null) (widget: null, renderer: null, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: platform:/plugin/org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.minmax.TrimStack, object: null) winBounds = Rectangle {79, 32, 1024, 768} winCenterX = 512 stackCtrl = null ----------------------- Stack values at at MinMaxAddon#tagChangeListener's #handleEvent: ----------------------- event = org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/application/ApplicationElement/tags/ADD] changedObject = org.eclipse.e4.ui.model.application.ui.advanced.impl.PlaceholderImpl@486985a3 (elementId: org.eclipse.ui.editorss, tags: [MinimizedByZoom, Minimized], contributorURI: null) (widget: null, renderer: null, toBeRendered: false, onTop: false, visible: true, containerData: 6000, accessibilityPhrase: null) (closeable: false) tag = Minimized oldVal = null ----------------------- Stack: Daemon Thread [Thread-1] (Suspended (exception NullPointerException)) MinMaxAddon.createTrim(MUIElement) line: 592 MinMaxAddon.minimize(MUIElement) line: 451 MinMaxAddon$6.handleEvent(Event) line: 297 UIEventHandler$1.run() line: 41 UISynchronizer(Synchronizer).syncExec(Runnable) line: 180 UISynchronizer.syncExec(Runnable) line: 150 Display.syncExec(Runnable) line: 4614 E4Application$1.syncExec(Runnable) line: 185 UIEventHandler.handleEvent(Event) line: 38 EventHandlerWrapper.handleEvent(Event, Permission) line: 197 EventHandlerTracker.dispatchEvent(EventHandlerWrapper, Permission, int, Event) line: 197 EventHandlerTracker.dispatchEvent(Object, Object, int, Object) line: 1 EventManager.dispatchEvent(Set, EventDispatcher, int, Object) line: 230 ListenerQueue.dispatchEventSynchronous(int, Object) line: 148 EventAdminImpl.dispatchEvent(Event, boolean) line: 135 EventAdminImpl.sendEvent(Event) line: 78 EventComponent.sendEvent(Event) line: 39 EventBroker.send(String, Object) line: 81 UIEventPublisher.notifyChanged(Notification) line: 55 PlaceholderImpl(BasicNotifierImpl).eNotify(Notification) line: 380 EDataTypeUniqueEList<E>(EcoreEList<E>).dispatchNotification(Notification) line: 255 EDataTypeUniqueEList<E>(NotifyingListImpl<E>).addUnique(E) line: 310 EDataTypeUniqueEList<E>(AbstractEList<E>).add(E) line: 307 MinMaxAddon.maximize(MUIElement) line: 519 MinMaxAddon$6.handleEvent(Event) line: 299 UIEventHandler$1.run() line: 41 UISynchronizer(Synchronizer).syncExec(Runnable) line: 180 UISynchronizer.syncExec(Runnable) line: 150 Display.syncExec(Runnable) line: 4614 E4Application$1.syncExec(Runnable) line: 185 UIEventHandler.handleEvent(Event) line: 38 EventHandlerWrapper.handleEvent(Event, Permission) line: 197 EventHandlerTracker.dispatchEvent(EventHandlerWrapper, Permission, int, Event) line: 197 EventHandlerTracker.dispatchEvent(Object, Object, int, Object) line: 1 EventManager.dispatchEvent(Set, EventDispatcher, int, Object) line: 230 ListenerQueue.dispatchEventSynchronous(int, Object) line: 148 EventAdminImpl.dispatchEvent(Event, boolean) line: 135 EventAdminImpl.sendEvent(Event) line: 78 EventComponent.sendEvent(Event) line: 39 EventBroker.send(String, Object) line: 81 UIEventPublisher.notifyChanged(Notification) line: 55 PartStackImpl(BasicNotifierImpl).eNotify(Notification) line: 380 EDataTypeUniqueEList<E>(EcoreEList<E>).dispatchNotification(Notification) line: 255 EDataTypeUniqueEList<E>(NotifyingListImpl<E>).addUnique(E) line: 310 EDataTypeUniqueEList<E>(AbstractEList<E>).add(E) line: 307 MinMaxAddon.setState(MUIElement, String) line: 184 MinMaxAddon.access$1(MinMaxAddon, MUIElement, String) line: 177 MinMaxAddon$2.mouseDoubleClick(MouseEvent) line: 140 TypedListener.handleEvent(Event) line: 195 EventTable.sendEvent(Event) line: 84 Display.sendEvent(EventTable, Event) line: 4129 CTabFolder(Widget).sendEvent(Event) line: 1457 CTabFolder(Widget).sendEvent(int, Event, boolean) line: 1480 CTabFolder(Widget).sendEvent(int, Event) line: 1465 CTabFolder(Widget).notifyListeners(int, Event) line: 1270 Display.runDeferredEvents() line: 3975 Display.readAndDispatch() line: 3614 PartRenderingEngine$9.run() line: 976 Realm.runWithDefault(Realm, Runnable) line: 332 PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 892 E4Workbench.createAndRunUI(MApplicationElement) line: 90 Workbench$3.run() line: 565 Realm.runWithDefault(Realm, Runnable) line: 332 Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 520 PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149 PowerExplorerApplication.start(IApplicationContext) line: 81 EclipseAppHandle.run(Object) line: 196 EclipseAppLauncher.runApplication(Object) line: 110 EclipseAppLauncher.start(Object) line: 79 EclipseStarter.run(Object) line: 352 EclipseStarter.run(String[], Runnable) line: 179 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 Method.invoke(Object, Object...) line: 597 Main.invokeFramework(String[], URL[]) line: 624 Main.basicRun(String[]) line: 579 Main.run(String[]) line: 1431 Main.main(String[]) line: 1407

Files changed in fix:
bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/minmax/MinMaxAddon.java