Eclipse Common Navigator Framework in RCP Applications
Eclipse is- amongst being an IDE and almost everything else- a powerful development environment for cross-platform rich client applications (RCP).
One particular feature of the Eclipse IDE is the framework for working with resource, more specifically the workspace resources. Michael Elder documented the Common Navigator Framework (CNF) in a series of articles in his blog.
Unfortunately, at the time of writing, CNF does not easily lend itself to use in RCP applications. A number of usenet postings and Eclipse bugs describes this problem. While a number of things still needs to be done to externalize the CNF API from the Eclipse IDE to allow clean use in RCP apps, a working solution exists today.
The following solution is derived from the sources mentioned above, full credit given:
- ApplicationWorkbenchAdvisor
public void initialize(IWorkbenchConfigurer configurer) {
configurer.setSaveAndRestore(true);
declareWorkbenchImages();
}@Override
public IAdaptable getDefaultPageInput() {
return new NavigatorRoot();
}public void preStartup() {
WorkbenchAdapterBuilder.registerAdapters();
}
The code for declareWorkbenchImages() including declareWorkbenchImage() is copied from org.eclipse.ui.internal.ide.IDEWorkbenchAdvisor. - New NavigatorRoot class.
The new NavigatorRoot implements IPersistableElement. This ensures that the class can be persisted when saving the workbench state. Otherwise, the navigator root element is not read when restoring the workbench state.
public class NavigatorRoot implements IAdaptable, IPersistableElement, IElementFactory {
public NavigatorRoot() {
}public Object getAdapter(Class adapter) {
if (adapter == IPersistableElement.class)
return this;
if (adapter == IWorkbenchAdapter.class)
return ResourcesPlugin.getWorkspace().getRoot().getAdapter(adapter);
return null;
}public String getFactoryId() {
return this.getClass().getCanonicalName();
}public void saveState(IMemento memento) {
// TODO Auto-generated method stub
return;
}public IAdaptable createElement(IMemento memento) {
return ResourcesPlugin.getWorkspace().getRoot();
}
} - ElementsFactory Extension.
To be sure the NavigatorRoot class can be instantiated when reading the workbench state, it’s createElement() method must be available. This is achieved in the previous chapter by implementing IElementFactory and now registering it in the elementsFactory extension in plugin.xml:
extension point="org.eclipse.ui.elementFactories"
factory class="rcpCNF.NavigatorRoot" id="rcpCNF.NavigatorRoot"At this point the navigator is already fully functional- but does not yet show any data/projects or actions to act on the data.
- Configure the Navigator
To use the new navigator, the navigator must be configured and content needs to be added. This is done by using the org.eclipse.ui.navigator.viewer extension.
Using this extension, we declare:- Which viewer we’d like to configure (viewer).
- Which content we’d like the viewer to display (viewerContentBinding).
- And which actions to expose to the user (viewerActionBinding).
A working example with full source code is available here in this RCP Navigator Example (updated).
November 30th, 2006 at 11:01 am
Sorry for the broken layout. WordPress is just f*!ck$ng incapable of not screwing up HTML source code.
December 12th, 2006 at 10:30 am
I’ve updated the post with step 4) to populate the navigator.
January 16th, 2007 at 11:03 pm
Hi Andreas,
You are awesome. I’ve been working with your example. In my environment, if I start with a scratch workspace, then create a “General Project” using the wizard, the project gets created on disk, but the Navigator never shows it. I can create many projects, refresh, refresh.. and I see nothing. Restarting does show it, and everything works as expected from there.
Eclipse 3.2.1
Java 5
Have you seen this before?
Many thanks!
January 17th, 2007 at 12:25 am
Duh, I now see from the original pos that you HAVE seen this before. But it l seems that your sample still behaves this way out of the box. Any ideas?
BTW, I’m debugging and I see different behavior during start up in the two scenarios (scratch wkspc vs. existing wkspc).
The diffs are..
scratch – getDefaultPageInput() is called, createElement() is not
existing – createElement() is called, getDefaultPageInput() is not
hmmm….
confused but not defeated.
January 17th, 2007 at 12:49 am
HMMMMMM…
deleted NavigatorRoot class…
deleted elementFactory previously added to plugin.xml
replaced getDefaultPageInput in hack to
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
return root;
Voila! Everything seems to work perfectly. Scratch, scratch..
Still seem to need the AdvisorHack though.
Baffled… but happy!:)
(all jokes aside, maybe I’ll dig further into this in the future, but for now, I’m assuming I missed someone’s advice somewhere, and moving on).
Eclipse
Version: 3.2.1
Build id: M20060921-0945
March 1st, 2007 at 11:05 pm
I understand that this has been reported before, however I wonder if the problem has cropped up again under 322.
I have tried rcpcnf.zip with Eclipse 322 on both Windows (JRE 1.5.0_11) & MacOS (JRE 1.5.0_06). In both cases I saw the same behavior reported by Jef Gearhart. New projects don’t show up unless their parent directory exists at runtime, for example, runtime-rcpCNF.product. The same is true when a product is exported via the product export wizard.
I would appreciate any help in this regard. Thanks in advance,
John Emerson
March 16th, 2007 at 3:00 pm
Didn’t look into this for some time but would be happy if anybody could find a solution- Jef?
Andreas
March 21st, 2007 at 1:33 am
Jef’s solution works with eclipse33M5eh. I’m curious to know when this workaround will be incorporated into 3.3. I incorrectly assumed it already had been in 33M5eh.
April 20th, 2007 at 5:09 pm
[...] developers have gone through a lot of pain trying to get the CNF to work, and most of these attempts involve trying to fake out the mechanism [...]
April 30th, 2007 at 1:58 pm
Hi This problem of no images nor project name in the navigator explorer..
it can be resolved by capturing the total code from the IDEWorkbenchAdvisor.java into your advisor class of your own RCP and then run the application.
I tried now my previous problem what i was getting of no name nor icon is resolved…
Thank god………………….
I struggled a lot
May 24th, 2007 at 11:43 pm
In 3.3 I20070524 on Vista, I took the example attached and was able to get it to work by replacing getDefaultPageInput with
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
return root;
as Jef suggested in his comment January 17th, 2007, but with no other changes suggested.
Note that the following line from the example in WorkbenchAdvisorHack.declareWorkbenchImages() now results in a compile error:
declareWorkbenchImage(ideBundle, IDEInternalWorkbenchImages.IMG_LCL_LINKTO_HELP,
because that key IMG_LCL_LINKTO_HELP no longer exists.
May 25th, 2007 at 5:44 am
Yes – see https://bugs.eclipse.org/bugs/show_bug.cgi?id=153933 – declaring that image should not be required anymore as of 3.3 RC1.
November 27th, 2007 at 2:13 am
This works well, but I’m needing to use a resource navigator cnf in an Eclipse RCP with workspace switching. This cnf example ignores any attempt to switch workspaces using the an Eclipse RCP application.
Just add the following code to the fillMenuBar method in ApplicationActionBarAdvisor to see what I mean:
IWorkbenchAction switchWorkspacehAction = IDEActionFactory.OPEN_WORKSPACE.create(window);
menuBar.add(switchWorkspacehAction);
Does anyone have any recommendations about how to get Eclipse workspace switching working with this cnf example?
Any advice would be great, because I’m really stuck
.
May 26th, 2008 at 4:12 pm
Thank you very much for your example. After downloading the available ZIP-file it was possible for me to implement the navigator view.
June 1st, 2008 at 12:47 pm
Hi Andreas,
I don’t know if you can point me in the right direction?
I’m stuck! My RCP Project uses the CNF heavily to display Workspace resources, but I need to remove the Copy, Paste, Delete, Move and Rename actions from the pop-up menu. I’ve been looking for some time, but have found no solution, just similar unanswered questions. Any suggestions would be greatly appreciated!
June 1st, 2008 at 1:08 pm
Check this out, too:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=145233
Francis is planning to spend some efforts on this.
June 3rd, 2008 at 10:10 pm
Also see this regarding restoring editor state:
http://www.sdtimes.com/content/article.aspx?ArticleID=30125
This is the reason why createElement and the navigator root classed are needed, while not really utilized in the example I had provided.
June 3rd, 2008 at 10:22 pm
And this for an alternative approach:
http://rcpquickstart.wordpress.com/2007/04/20/using-the-common-navigator-framework-in-an-rcp-application/
June 17th, 2008 at 8:46 am
Thanks for the reply. I tried setting allowPlatformContributions to false, but the group.edit and group.reorganise groups still seem to be being populated! I didn’t expect that!
I’m unsure how to stop it, because I need to prevent or override delete / copy / paste types of actions. I’ve tried not adding the insertionPoint for group.edit and group.reorganize – which works, but it writes out “group not found” exceptions to the log. From a support perspective, that isn’t acceptable.
Any suggestions, this is starting to become a major issue for the project…
June 24th, 2008 at 1:10 am
Hi andig,
Thanks for getting back to me. I’ve read the links you mentioned but I’m still stuck. It’s been suggested that I define a viewer with a blank popup like this:
I agree that this should work, but I still get the copy, paste, delete, move and rename actions (from the “group.edit” and “group.reorganize” groups). If I define my own viewer popup insertionPoints and leave out those two groups, I get java.lang.IllegalArgumentExceptions: Group not found exceptions written to my log.
I am baffled as to why those two groups insist on being there. I am desperate for a solution because this issue has now become critical blocker to my project.
Many thanks
Greg.
June 24th, 2008 at 1:38 am
…and here is my plugin.xml section for the cnf:
My CustomCommonNavigator does work fine – it just extends the CommonNavigator Class and overrides the single getInitialInput method with the following code:
@Override
protected IAdaptable getInitialInput() {
return ResourcesPlugin.getWorkspace().getRoot();
}
June 24th, 2008 at 2:56 am
…my plugin.xml didn’t come through for some reason. I’ll try again, this time I’ve replaced the greater and less-than characters with square brackets. Sorry for littering you’re page:
[extension point="org.eclipse.ui.navigator.viewer"]
[viewer popupMenuId="mynavigatorpopup" viewerId="mynavigator"]
[popupMenu allowsPlatformContributions="false" id="mynavigatorpopup"]
[insertionPoint name="mygroup"/]
[/popupMenu]
[/viewer]
[viewerContentBinding viewerId="mynavigator"]
[includes]
[contentExtension pattern="org.eclipse.ui.navigator.resourceContent"/]
[contentExtension pattern="org.eclipse.ui.navigator.resources.filters.*"/]
[/includes]
[/viewerContentBinding]
[/extension]
[extension point="org.eclipse.ui.navigator.navigatorContent"]
[navigatorContent id="mynavigator"
contentProvider="org.eclipse.ui.internal.navigator.resources.workbench.ResourceExtensionContentProvider"
labelProvider="org.eclipse.ui.internal.navigator.resources.workbench.ResourceExtensionLabelProvider"
name="gov.dsto.vipa.workbench.navigatorContent2"/]
[/extension]
[extension point="org.eclipse.ui.views"]
[view id="mynavigator" class="mypackage.CustomCommonNavigator" name="Navigator"/]
[/extension]
February 9th, 2009 at 9:00 pm
Eclipse Help has been updated with CNF info- including description as to how to use it in RCP applications:
http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/cnf.htm
May 21st, 2009 at 12:54 am
Dude.. Thank you so much, this framework sucks for using alone in RCP, I was finally able to the images to be displayed after looking at what you did in your example WorkbenchAdvisorHack .. much appreciated. this was a good
wasted 4 hours
May 29th, 2009 at 11:43 pm
[...] http://www.cpuidle.de/blog/?p=48 [...]