Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » NatTable and context menu from fragment.e4xmi(NatTable and context menu from fragment.e4xmi)
NatTable and context menu from fragment.e4xmi [message #1698118] Thu, 11 June 2015 12:29 Go to next message
Andriy Golovko is currently offline Andriy GolovkoFriend
Messages: 4
Registered: June 2015
Junior Member
Hi,

the context menu on the NatTable is created in my code in essence in the same way as it is
proposed by Lars in his post nattable-context-menus-with-eclipse-menus:


I use the nattable 1.3.0 (1.3.0.201503261201) with e4.

For me the approach works fine as long I have only one instance of the NatTable and
it is not re-opened. But unfortunately in our scenario the NatTable is located in
a part which can be reopened. As consequence, the context menu must be called more than
only one time (the following code is executed more than one time accordingly).

The first run of the following code register the context menu M on the natTable as expected,
the M is populated with menu items A B C and so on:

@Creatable
public class TableContextMenuConfiguration extends AbstractUiBindingConfiguration {

	@Inject
	private EMenuService menuService;

	@Override
	public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {

		menuService.registerContextMenu(this.natTable, CONTEXT_MENU_KEY);

		// hack which works. But the menu items optionally contributed 
		// from other plugins effectively missed in such way
		// final Menu defaultMenu = new Menu(natTable);
		final Menu defaultMenu = natTable.getMenu();
		natTable.setMenu(null);


		PopupMenuBuilder pmBuilder = new PopupMenuBuilder(natTable, defaultMenu)
				.withMenuItemProvider(MenuItemProviders.selectFilterMenuItemProvider(staticFilterMatcher, grid))
				.withMenuItemProvider(MenuItemProviders.clearFilterMenuItemProvider(staticFilterMatcher, grid)).
				/*.withSeparator().*/withMenuItemProvider(MenuItemProviders.copyCellMenuItemProvider())
				.withMenuItemProvider(MenuItemProviders.copyRowMenuItemProvider());
		pmBuilder.build();
	}
}


The problem is, that the successive calls to registerContextMenu() results in reuse of the M,
which already have menu items A B C. As consequence, the menu items appears doubled
after the second call of the code above. The problem is even worse: the A B C menu items
are left from the previous instance of the NatTable and are already disposed. This disposed
state results in "Widget is disposed" Exception only for the commented /*withSeparator()*/
menu item. The cause of the exception is basically the PopupMenuBuilder.java:734, which try
to operate on disposed separator:
!STACK 0
org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: Widget is disposed
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:62)
	at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:888)
	at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:120)
	at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:337)
	at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:258)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:162)
	at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:104)
	at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:73)
	at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:55)
	at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:127)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:983)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$6.run(PartRenderingEngine.java:547)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:531)
	at org.eclipse.e4.ui.workbench.renderers.swt.ElementReferenceRenderer.createWidget(ElementReferenceRenderer.java:69)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:983)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:766)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:737)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:731)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:715)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$1.handleEvent(PartRenderingEngine.java:141)
	at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40)
	at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:187)
	at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:156)
	at org.eclipse.swt.widgets.Display.syncExec(Display.java:4732)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:218)
	at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36)
	at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)
	at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)
	at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
	at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
	at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)
	at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)
	at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)
	at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:81)
	at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:59)
	at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)
	at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setToBeRendered(UIElementImpl.java:303)
	at org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.showElementInWindow(ModelServiceImpl.java:485)
	at org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.bringToTop(ModelServiceImpl.java:454)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.delegateBringToTop(PartServiceImpl.java:705)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:682)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:620)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:608)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.showPart(PartServiceImpl.java:1137)
	at org.eclipse.ui.internal.WorkbenchPage.showPart(WorkbenchPage.java:1292)
	at org.eclipse.ui.internal.WorkbenchPage.busyShowView(WorkbenchPage.java:1283)
	at org.eclipse.ui.internal.WorkbenchPage$14.run(WorkbenchPage.java:4208)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ui.internal.WorkbenchPage.showView(WorkbenchPage.java:4204)
	at org.eclipse.ui.internal.WorkbenchPage.showView(WorkbenchPage.java:4184)
	at org.eclipse.ui.handlers.ShowViewHandler.openView(ShowViewHandler.java:127)
	at org.eclipse.ui.handlers.ShowViewHandler.openOther(ShowViewHandler.java:100)
	at org.eclipse.ui.handlers.ShowViewHandler.execute(ShowViewHandler.java:68)
	at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:294)
	at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:90)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:247)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:229)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:132)
	at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:149)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:499)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
	at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:210)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:825)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.handleWidgetSelection(HandledContributionItem.java:701)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.access$6(HandledContributionItem.java:685)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem$4.handleEvent(HandledContributionItem.java:613)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4199)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1467)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1490)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1475)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1279)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4042)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3669)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:636)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at c.n.p.workbench.application.Application.start(Application.java:21)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1465)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1438)
Caused by: org.eclipse.swt.SWTException: Widget is disposed
	at org.eclipse.swt.SWT.error(SWT.java:4441)
	at org.eclipse.swt.SWT.error(SWT.java:4356)
	at org.eclipse.swt.SWT.error(SWT.java:4327)
	at org.eclipse.swt.widgets.Widget.error(Widget.java:783)
	at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:573)
	at org.eclipse.swt.widgets.Widget.getData(Widget.java:874)
	at org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder$PopupContributionItem.isVisible(PopupMenuBuilder.java:734)
	at org.eclipse.jface.action.MenuManager.isChildVisible(MenuManager.java:1040)
	at org.eclipse.jface.action.MenuManager.update(MenuManager.java:802)
	at org.eclipse.jface.action.MenuManager.update(MenuManager.java:721)
	at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.processContents(MenuManagerRenderer.java:622)
	at org.eclipse.e4.ui.internal.workbench.swt.MenuService.registerMenu(MenuService.java:74)
	at org.eclipse.e4.ui.internal.workbench.swt.MenuService.registerContextMenu(MenuService.java:38)
	at c.n.p.o.table.ui.parts.table.configs.TableContextMenuConfiguration.configureUiBindings(TableContextMenuConfiguration.java:100)
	at org.eclipse.nebula.widgets.nattable.NatTable.configure(NatTable.java:586)
	at c.n.p.o.table.ui.parts.table.Grid.createControl(Grid.java:334)
	at c.n.p.o.table.ui.parts.TablePart.createComposite(TablePart.java:164)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55)
	... 105 more
 



My question 1: is it any way to remove menu items from nattable context menu as soon as the nattable is disposed?

My question 2: is it any other way to register menues for the NatTable.


I tried to define not only "Popup Menu", but also Command + Handler in the fragement.e4xmi file.
But this solution had as result:
- the menu items in the popup menu were thus visible, but disabled (the handler class was not invoked at all)
- the click on the head of the NatTable opened my contetext menu from fragment.e4xmi. After close of
my menu the NatTable standard menu appears.
Re: NatTable and context menu from fragment.e4xmi [message #1698516 is a reply to message #1698118] Tue, 16 June 2015 08:04 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2526
Registered: July 2012
Senior Member
Quote:
proposed by Lars in his post nattable-context-menus-with-eclipse-menus


It was Lars post? Really?

Quote:
The problem is, that the successive calls to registerContextMenu() results in reuse of the M, which already have menu items A B C.


Well, this is because there is only one Eclipse menu instance in the application model, while the NatTable context menu is per NatTable instance. So it is not the registerContextMenu() call that adds the menu items multiple times, it is the PopupMenuBuilder that adds the NatTable items again.

Quote:
The cause of the exception is basically the PopupMenuBuilder.java:734, which try to operate on disposed separator


From the stacktrace the menu instance is disposed, not the menu item.

Quote:
My question 1: is it any way to remove menu items from nattable context menu as soon as the nattable is disposed?


None I'm aware of. You could file an enhancement request so we can add such a method.

Quote:
My question 2: is it any other way to register menues for the NatTable.


The usage of Eclipse menus for NatTable is a special use case, not the default. It is only needed in case you want to have additional menu items in the NatTable context menu that are defined in the application model. If you only have NatTable related menu items, the better approach is to only use the PopupMenuBuilder without an Eclipse menu

@Creatable
public class TableContextMenuConfiguration extends AbstractUiBindingConfiguration {

	@Override
	public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {

		PopupMenuBuilder pmBuilder = new PopupMenuBuilder(natTable)
				.withMenuItemProvider(MenuItemProviders.selectFilterMenuItemProvider(staticFilterMatcher, grid))
				.withMenuItemProvider(MenuItemProviders.clearFilterMenuItemProvider(staticFilterMatcher, grid)).
				.withSeparator().withMenuItemProvider(MenuItemProviders.copyCellMenuItemProvider())
				.withMenuItemProvider(MenuItemProviders.copyRowMenuItemProvider());
		pmBuilder.build();
	}
}


This should be sufficient and preferred if you don't need to include other menu items than the NatTable menu items.

Re: NatTable and context menu from fragment.e4xmi [message #1699304 is a reply to message #1698516] Tue, 23 June 2015 10:29 Go to previous message
Andriy Golovko is currently offline Andriy GolovkoFriend
Messages: 4
Registered: June 2015
Junior Member
Hi Dirk, thank you for answer.

Sorry for referencing wrong author of the blog post. My sentence must be read of course as:

"the context menu on the NatTable is created in my code in essence in the same way as it is
proposed by Dirk Fauth in his post nattable-context-menus-with-eclipse-menus".

[Updated on: Tue, 23 June 2015 10:29]

Report message to a moderator

Previous Topic:org.eclipse.core.runtime error on migration to Eclipse luna 4.4.2
Next Topic:P2 UIs in Eclipse 4
Goto Forum:
  


Current Time: Fri Nov 24 15:11:26 GMT 2017

Powered by FUDForum. Page generated in 0.21921 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software