Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Add menu item to menu at runtime
Add menu item to menu at runtime [message #881071] Sun, 03 June 2012 20:46 Go to next message
Lisi Blümelhuber is currently offline Lisi Blümelhuber
Messages: 5
Registered: June 2012
Junior Member
Hello,

I need to create a submenu which is filled with elements at runtime.

I didn't find any examples or any easy way to do it, so I've implemented it via a crude "iterate over menus to find the correctly named menu, and then add MMenuElements to it".

Corresponding code in the handler:

@PostConstruct
	public void init() {
		for (final String filename : Constants.recentlyUsedFilesList) {
			DynamicMenuHelper.addMenuItemToMenu(application, "recentfiles.menu", 
					filename, "bundleclass://handlers.file.RecentFilesHandler");
		}	
	}

@PreDestroy
	public void cleanup() {
		for (final String filename : Constants.recentlyUsedFilesList) {
			DynamicMenuHelper.removeMenuItemFromMenu(application, "recentfiles.menu", filename);
		}
	}


This correctly adds the MMenuElements to the menu and seemingly also removes them, but obviously the state gets saved before the @PreDestroy method is called (I mean the "runtime" folder in the Eclipse workspace), so the menu elements don't get removed and multiply each time the application starts.

Can anyone point me in the right direction to do this?
Re: Add menu item to menu at runtime [message #881081 is a reply to message #881071] Sun, 03 June 2012 21:20 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

Lisi Blümelhuber wrote on Sun, 03 June 2012 23:46

I need to create a submenu which is filled with elements at runtime.


Use MMenuFactory to create the elements and then add or remove them to the children of the parent menu.

//creation
MDirectMenuItem dynamicItem = MMenuFactory.INSTANCE.createDirectMenuItem();
		dynamicItem.setLabel("Testing");
//addition 
menu.getChildren().add(dynamicItem);

where menu is the parent MMenu
Re: Add menu item to menu at runtime [message #881102 is a reply to message #881081] Sun, 03 June 2012 22:46 Go to previous messageGo to next message
Lisi Blümelhuber is currently offline Lisi Blümelhuber
Messages: 5
Registered: June 2012
Junior Member
I do exactly that, and adding works fine.

It's removing items that doesn't work - the function marked with @PreDestroy gets executed and the list (of the menu children) gets reduced as I intend, but when I start the application again, the menu items that should have been removed are still there, plus one full set of new menu items.

Only way to avoid this is to manually delete the "runtimeXYZ" folder in the Eclipse workspace.

MMenu target = (MMenu) findMenuElement(application, menuElementId);
		List<MMenuElement> elements = target.getChildren();
		List<MMenuElement> found = new ArrayList<MMenuElement>();
		for (MMenuElement element: elements) {
			if (element.getLabel() != null && element.getLabel().equals(menuItemLabel)) {
				found.add(element);
			}
		}
		target.getChildren().removeAll(found);

[Updated on: Sun, 03 June 2012 22:49]

Report message to a moderator

Re: Add menu item to menu at runtime [message #881106 is a reply to message #881102] Sun, 03 June 2012 22:58 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

On your run configuration -> main tab -> check 'Clear' and select 'workspace' -> apply

However it looks like when you remove the items, they don't get removed from the model and when the app runs again it loads the model which the previous launch left with the items in the model.
Re: Add menu item to menu at runtime [message #881241 is a reply to message #881106] Mon, 04 June 2012 07:54 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph Keimel
Messages: 356
Registered: December 2010
Location: Germany
Senior Member
maybe you could remove the menu items on @PersistState instead of @PreDestroy?
Re: Add menu item to menu at runtime [message #881346 is a reply to message #881241] Mon, 04 June 2012 11:34 Go to previous messageGo to next message
Brian de Alwis is currently offline Brian de Alwis
Messages: 242
Registered: July 2009
Senior Member
@PersistState is a good suggestion normally, except tht could be called at an arbitrary time with execution continuing afterwards. I see it best used to synchronize the model state with our part state.

Checking or and removing the old menu on startup is likely your best option for now. Perhaps we should have a "transient" tag Or flag for model elements so tt they aren't persisted. There's been some discussion on:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=378815

Brian,
Re: Add menu item to menu at runtime [message #881503 is a reply to message #881346] Mon, 04 June 2012 17:39 Go to previous messageGo to next message
Lisi Blümelhuber is currently offline Lisi Blümelhuber
Messages: 5
Registered: June 2012
Junior Member
First of all, thanks for your input so far!

Sopot Cela wrote on Sun, 03 June 2012 18:58
On your run configuration -> main tab -> check 'Clear' and select 'workspace' -> apply

However it looks like when you remove the items, they don't get removed from the model and when the app runs again it loads the model which the previous launch left with the items in the model.


Clearing the workspace works, but my impression is exactly what you wrote in your last sentence - the model stays the same, and that's unacceptable for the release application.


Christoph Keimel wrote on Mon, 04 June 2012 03:54
maybe you could remove the menu items on @PersistState instead of @PreDestroy?


I tried that, but the method then does not get called at exiting the application.

Brian de Alwis wrote on Mon, 04 June 2012 07:34
... Checking or and removing the old menu on startup is likely your best option for now.


Do you mean the menu where I want to put the dynamically generated menu items into or the menu items?
When I simply remove the menu items from the menu
target.getChildren().clear();
, on first click on one of the menu items I get a fat stacktrace with no functions of my own involved - after that, the menu items in the menu are unlabeled and throw further exceptions or do nothing when being clicked.

java.lang.NullPointerException
	at org.eclipse.e4.ui.workbench.renderers.swt.DirectContributionItem.getExecutionContext(DirectContributionItem.java:476)
	at org.eclipse.e4.ui.workbench.renderers.swt.DirectContributionItem.executeItem(DirectContributionItem.java:450)
	at org.eclipse.e4.ui.workbench.renderers.swt.DirectContributionItem.handleWidgetSelection(DirectContributionItem.java:360)
	at org.eclipse.e4.ui.workbench.renderers.swt.DirectContributionItem.access$1(DirectContributionItem.java:344)
	at org.eclipse.e4.ui.workbench.renderers.swt.DirectContributionItem$2.handleEvent(DirectContributionItem.java:301)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4169)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3758)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1021)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:915)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:150)
	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:353)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
	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:629)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1414)


I really thought that implementing a "recent files" menu would be a very simple feature to implement - maybe I'm overlooking something terribly obvious (this framework is new to me)?
Re: Add menu item to menu at runtime [message #881513 is a reply to message #881503] Mon, 04 June 2012 18:17 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

Lisi, if you could post a zip attachment with a small sample project showing this situation we would be happy to help out.
Re: Add menu item to menu at runtime [message #881546 is a reply to message #881513] Mon, 04 June 2012 20:07 Go to previous messageGo to next message
Lisi Blümelhuber is currently offline Lisi Blümelhuber
Messages: 5
Registered: June 2012
Junior Member
That would of course be great - the example is as small as it gets Smile.

There is some unnecessary recursion in the RecentFilesHandler.init() (pointing to itself), but creating another handler class doesn't change the relevant behavior.
  • Attachment: menudemo.zip
    (Size: 10.70KB, Downloaded 150 times)
Re: Add menu item to menu at runtime [message #881573 is a reply to message #881546] Mon, 04 June 2012 21:23 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

Try adding
((EObject)application).eResource().save(null);

as the last line of the predestroy method after
DynamicMenuHelper.clearMenu(application, "menudemo.recentfiles.menu"); 
Re: Add menu item to menu at runtime [message #881879 is a reply to message #881573] Tue, 05 June 2012 12:15 Go to previous messageGo to next message
Lisi Blümelhuber is currently offline Lisi Blümelhuber
Messages: 5
Registered: June 2012
Junior Member
Working perfectly in both the sample project and the real one.

Thank you for your time and effort!
Re: Add menu item to menu at runtime [message #985880 is a reply to message #881879] Fri, 16 November 2012 14:43 Go to previous message
Mateusz Krzysztoń is currently offline Mateusz Krzysztoń
Messages: 1
Registered: November 2012
Junior Member
Hi,

thank you for solution above, it was very helpful. However, I have problem with finding which element of the Menu was clicked in execute method of handler. I would be grateful for any hint.

[EDIT] Solution is of course commands parameter..

[Updated on: Fri, 16 November 2012 17:20]

Report message to a moderator

Previous Topic:How to get the closest IEclipseContext of a MPartStack?
Next Topic:How can I check if a part is active and has the focus?
Goto Forum:
  


Current Time: Wed Oct 01 00:01:50 GMT 2014

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

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