Magic Required to use the Common Navigator in an RCP Application that uses Resources

At this point, the only source of useful overview documentation for the Common Navigator are the excellent tutorials at Michael Elder’s (the author of the CN) blog. Soon I hope to get some of this transferred into the Eclipse Plugin Developer’s Guide.

RCP applications can quickly and easily use the CN to show the resources in the workspace.  This assumes that your RCP application uses resources (which is another discussion).  The CN can also be used for non-resource RCP applications, in that case, these instructions don’t apply, as the objects treated by the CN have to be created directly by the RCP application.

If you are planning to use the CN in an RCP application that uses resources, there are 3 (2 of which are completely undocumented) things you must do:

  1. Call org.eclipse.ui.internal.ide.model.WorkbenchAdapterBuilder.registerAdapters() in your WorkbenchAdvisor initialize() or preStartup() methods. (You also need to do this if you are planning on using the older Resource Navigator). This hooks up the adapters from the core (mainly resource) components to the navigator support.
  2. To get the icons for projects correctly registered, you need to execute this code also in the WorkbenchAdvisor initialize() or preStartup() methods:
    
    final String ICONS_PATH = "icons/full/";
    final String PATH_OBJECT = ICONS_PATH + "obj16/";
    Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH);
    declareWorkbenchImage(configurer, ideBundle, IDE.SharedImages.IMG_OBJ_PROJECT,
        PATH_OBJECT + "prj_obj.gif", true);
    declareWorkbenchImage(configurer, ideBundle, IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED,
        PATH_OBJECT + "cprj_obj.gif", true);
    
    ...
    
    private void declareWorkbenchImage(IWorkbenchConfigurer configurer_p, Bundle ideBundle, String symbolicName,
    String path, boolean shared) {
       URL url = ideBundle.getEntry(path);
       ImageDescriptor desc = ImageDescriptor.createFromURL(url);
       configurer_p.declareImage(symbolicName, desc, shared);
    }
    
  3. Hook the root of the CN up to the workspace by adding this method to your WorkbenchAdvisor:
    public IAdaptable getDefaultPageInput()  {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        return workspace.getRoot();
    }

I realize having to use internal classes is not the way we want to do things, and there are currently some bugs outstanding about this that we hope to get resolved in 3.5 (not sooner because they would require API changes).

About these ads

About francisu

Senior Architect at Talend, responsible for data transformation and other cross-product issues. Also committer in Eclipse Platform UI (mainly Common Navigator) and maintainer of Jenkins EC2 plugin.
This entry was posted in Common Navigator. Bookmark the permalink.

7 Responses to Magic Required to use the Common Navigator in an RCP Application that uses Resources

  1. Patrick Paulin says:

    Hi Francis,

    Congratulations on becoming a committer and thanks (in advance) for all the work on the Commons Navigator. I think it could be an incredibly useful tool for RCP developers.

    I just wanted to get my request in to make the CNF more useful outside of the context of a workspace. Currently, you have to extend the CommonNavigator class to get this working as I write about in the following post:

    http://rcpquickstart.wordpress.com/2007/04/20/using-the-common-navigator-framework-in-an-rcp-application/

    I haven’t reviewed all of the Bugzilla entries related to the CNF but I’ll try to do that and submit something more descriptive. But apart from specific entries, I’d just like to suggest that you consider non-workspace scenarios as you do your work.

    Again, thanks for taking the time to make the CNF more useful.

    — Patrick

  2. Francis Upton says:

    Patrick, thanks for your comment (and your obfuscation work you did a while ago, I have happily used that). I read through the items you referred to, and I think all you have to do (for an RCP application) is what I have suggested in this post and it should work fine (as long as you also follow the tutorial and make sure you set the extension points correctly — but you can easily set the contentProvider to just refer to the contentProvider in org.eclipse.ui.navigator.resources). That’s what I do and it works fine in 3.4; I have just helped someone in the news do this on 3.3 and it works for them as well. If I’m missing the point here, please help me out.

    There seems to be a lot of discussion about getDefaultPageInput() being called; as far as I can see it’s always called in startup regardless of the state of the workspace.

    I’m not arguing that it’s as easy and well documented as it should be in working with RCP applications; much improvement is needed.

  3. Francis, nice to see you living up to those commit rights by working on this problem. I’m glad I voted +1 for you! :)

    The CN is tremendously useful but it can be quite a hill to climb. I tried to use a year ago for a hobby application and as you pointed out, the only good how-to’s were Michael Elder’s blog. More words in this area would surely ease and increase adoption.

    You’ve already touched on the deeper issues though around difficulty of use for non-resource items. In my brief usage, I was concerned whether the bang for buck was there for the average adopter.

  4. Will says:

    Has this changed with Eclipse 3.5?

    For one, you can call org.eclipse.ui.ide.IDE.registerAdapters() instead of org.eclipse.ui.internal.ide.model.WorkbenchAdapterBuilder.registerAdapters() to avoid using the internal (and now deprecated) class.

    At least in Ganymede help there was a section about RCP with essentially these instructions: http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/cnf_rcp.htm

    I don’t see similar instructions in the Galileo help.

  5. Francis Upton says:

    @Will, yes this has changed in 3.5 and the instructions were revised in 3.5 to reflect this. The new instructions refer to the new API. See this page: http://help.eclipse.org/galileo/topic/org.eclipse.platform.doc.isv/guide/cnf_steps_content.htm.

  6. Hendy says:

    The recommended way to do this now (as of Eclipse 3.5+) :


    public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
    ...
    @Override
    public void initialize(IWorkbenchConfigurer configurer) {
    super.initialize(configurer);
    //configurer.setSaveAndRestore(true); // if you want
    IDE.registerAdapters();
    }

  7. Is there an alternative to using IDEWorkbenchPlugin.getBundle() (which is internal and I guess should really not be used))?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s