tutorial : eclipse rcp e4 with 3.x views like project explorer, properties, etc.

This tutorial shows step-by-step how to add classical Eclipse 3.x views like Project Explorer and the Properties View to an Eclipse e4 Rich Client Platform (RCP) Application.

Eclipse 4.2 was released a few weeks ago with the new e4 platform that basically uses an EMF model to describe how your application looks and feels. While this is neat, the caveat is that e4 currently (August 2012) does not provide views for a number of core features of the old Eclipse 3.x platform including things like the Project Explorer, a Properties View and the like.

Eclipse 4.2 comes with a “Compatibility Layer” that makes all the old features that were not ported yet to e4 available. However, I could not find a site that tells me how to use it. There are a few quite instructive tutorials out there on how RCP applications with e4 work, for instance http://www.vogella.com/articles/EclipseRCP/article.html. But none showed me how to add a Project Explorer and all the IDE views that I needed for my projects (http://service-technology.org/seda and http://service-technology.org/greta in case you want to know). So I went for the usual approach in the Eclipse-verse: trial and error. Here is what I figured out and works for me.

For the rest of this tutorial I assume you are familiar with building Eclipse 3.X RCP applications. Please consult a more complete tutorial such as http://www.vogella.com/articles/EclipseRCP/article.html to get into the topic or refresh some details. To get a code-base to try out the things I talk about next, create a new RCP project using File > New Project > Plug-In Project, give it a name (let’s call it test.rcp here), and pick the Hello RCP Template to create the project.

  1. To use the “Compatibility Layer” of Eclipse 4, do not run an e4-based application, but run a classical Eclipse application. An Eclipse RCP consists of two things: an application, and a product. The product defines the look and feel of the RCP, the application provides the “framework” on which this look and feel can be pinned. e4 does not allow to pin the “Compatibility Layer”. Instead, we use a classical application (backed by Eclipse 4.X plugins) and add an “e4 aware product” on top of it. This solution has the drawback that some parts of your RCP application have to be defined in code. Yet some parts can be defined by the e4 model and become a lot easier.
  2. Add an e4 application model file to the RCP project: File > New > Eclipse 4 > Model > New Application Modeltest.rcp as container, give it the name Application.e4xmi, and check Include Default Addons. In this file we will later put all the fancy model definitions of our RCP application. But first we have to prepare a few other things.
  3. Register a new product definition in the RCP project: edit plugin.xml and insert the following product definition
    <extension id="product_test" point="org.eclipse.core.runtime.products">
      <product application="test.rcp.application" name="My Product">
        <property name="appName" value="My App"> </property>
        <property name="applicationXMI" value="test.rcp/Application.e4xmi"> </property>
      </product>
    </extension>
    

    where test.rcp.application refers to the Eclipse 3.X application defined in the RCP plugin at the org.eclipse.core.runtime.applications extension point, and test.rcp/Application.e4xmi refers to the application model file we just created.

  4. Create a new product configuration file using the File > New > Plug-In Development > Product Configuration wizard. Put the file in your RCP plugin (test.rcp), give it a name (test.rcp.product), and Initialize the file content using the existing product we just defined: test.rcp.product_test (where product_test stems from the id given in the extension point. You can configure various things like names and ids etc. The most important settings are the following.
  5. Link the product to Eclipse 3.X application by setting in test.rcp.product on the Overview Tab the Application to test.rcp.Application (as in the plugin.xml).
  6. Add required Eclipse 3.X and Eclipse e4 features to your product. To run the product, you will need a bunch of plugins and features from Eclipse which you can configure in the product configuration. Make it based on features (there are other solutions, but I prefer this one), open the Dependencies tab, add org.eclipse.e4.rcp and click the Add Required button which will add org.eclipse.emf.core and org.eclipse.emf.common to the product configuration.
  7. Define a Main Application Window. In the old eclipse world you would now be good to go and run the product. With e4, you aren’t. We have to define the look and feel of the application in the Application.e4xmi. Open the file and at Application > Windows add a new TrimmedWindow. You can configure various things here, but we will leave it for now.
  8. Run the application to test if things are good so far: right click on test.rcp.product and select Run As > Eclipse Application. The launch will probably fail, edit the launch configuration in Run > Run Configurations…, open the Plugins tab, select Launch with ‘plug-ins selected below only, check your RCP plugin test.rcp and click on Add Required Plug-ins to get all Eclipse plugins that are needed to run your application. When you click on Run an application windows looking like this should show up.

    In case your product does not launch and raises further errors, check whether there are VM arguments of your launch configuration that conflict with the available Java runtime.
  9. Define ‘shared elements’ that access Eclipse 3.x compatibility layer. Now comes the first step to actually enable Eclipse 3.x in your application. As the current editor for the Application.e4xmi has some limitations, we have to do some xml editing. Take a short-cut and replace the contents of your Application.e4.xmi with this code:
    <?xml version="1.0" encoding="UTF-8"?>
    <application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_VnmacNSzEeGBn6dQ9VPexA" elementId="test.rcp.application" bindingContexts="_VnmacdSzEeGBn6dQ9VPexA">
      <children xsi:type="basic:TrimmedWindow" xmi:id="_Vnmah9SzEeGBn6dQ9VPexA" label="My Main Window" iconURI="" width="800" height="600">
        <children xsi:type="advanced:PerspectiveStack" xmi:id="_Vnmaj9SzEeGBn6dQ9VPexA" selectedElement="_VnmakNSzEeGBn6dQ9VPexA">
          <children xsi:type="advanced:Perspective" xmi:id="_VnmakNSzEeGBn6dQ9VPexA" elementId="test.rcp.perspective" selectedElement="_VnnBgNSzEeGBn6dQ9VPexA" label="My Perspective" iconURI="">
            <tags>Perspective</tags>
            <tags>categoryTag:General</tags>
            <children xsi:type="basic:PartSashContainer" xmi:id="_VnnBgNSzEeGBn6dQ9VPexA" horizontal="true">
              <children xsi:type="basic:PartStack" xmi:id="_VnnBgdSzEeGBn6dQ9VPexA" containerData="3400">
                <tags>newtablook</tags>
                <tags>org.eclipse.e4.primaryNavigationStack</tags>
                <children xsi:type="advanced:Placeholder" xmi:id="_QR29cNS2EeGBn6dQ9VPexA" elementId="org.eclipse.ui.navigator.ProjectExplorer" ref="_sS7Q8NS1EeGBn6dQ9VPexA"/>
              </children>
              <children xsi:type="basic:PartSashContainer" xmi:id="_bTQ1YNS2EeGBn6dQ9VPexA" elementId="" containerData="10000">
                <children xsi:type="advanced:Placeholder" xmi:id="_hP-EYNS2EeGBn6dQ9VPexA" elementId="org.eclipse.ui.editorss" ref="_Hmg4kNSjEeGwXp2p959l3w"/>
                <children xsi:type="basic:PartStack" xmi:id="_qAHrYNS2EeGBn6dQ9VPexA" elementId="org.eclipse.ui.views.PropertySheetMStack" containerData="3400" selectedElement="_soNH8NS2EeGBn6dQ9VPexA">
                  <tags>newtablook</tags>
                  <tags>org.eclipse.e4.secondaryDataStack</tags>
                  <children xsi:type="advanced:Placeholder" xmi:id="_soNH8NS2EeGBn6dQ9VPexA" elementId="org.eclipse.ui.views.PropertySheet" ref="_WqRGcNS1EeGBn6dQ9VPexA"/>
                </children>
              </children>
            </children>
          </children>
        </children>
        <sharedElements xsi:type="advanced:Area" xmi:id="_Hmg4kNSjEeGwXp2p959l3w" elementId="org.eclipse.ui.editorss">
          <children xsi:type="basic:PartStack" xmi:id="_HmhfoNSjEeGwXp2p959l3w" elementId="org.eclipse.e4.primaryDataStack">
            <tags>newtablook</tags>
            <tags>org.eclipse.e4.primaryDataStack</tags>
            <tags>EditorStack</tags>
          </children>
        </sharedElements>
        <sharedElements xsi:type="basic:Part" xmi:id="_WqRGcNS1EeGBn6dQ9VPexA" elementId="org.eclipse.ui.views.PropertySheet" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView" label="Properties" iconURI="platform:/plugin/org.eclipse.ui.views//icons/full/eview16/prop_ps.gif" closeable="true">
          <tags>View</tags>
          <tags>categoryTag:General</tags>
          <menus xmi:id="_HngXENSjEeGwXp2p959l3w" elementId="org.eclipse.ui.views.PropertySheet">
            <tags>ViewMenu</tags>
            <tags>menuContribution:menu</tags>
          </menus>
          <toolbar xmi:id="_Hng-INSjEeGwXp2p959l3w" elementId="org.eclipse.ui.views.PropertySheet"/>
        </sharedElements>
        <sharedElements xsi:type="basic:Part" xmi:id="_sS7Q8NS1EeGBn6dQ9VPexA" elementId="org.eclipse.ui.navigator.ProjectExplorer" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView" label="Project Explorer" iconURI="platform:/plugin/org.eclipse.ui.navigator.resources//icons/full/eview16/resource_persp.gif">
          <tags>View</tags>
          <tags>categoryTag:General</tags>
          <menus xmi:id="_4UXAUNSmEeG-a6zBTyJ-wg" elementId="org.eclipse.ui.navigator.ProjectExplorer">
            <tags>ViewMenu</tags>
            <tags>menuContribution:menu</tags>
          </menus>
          <menus xsi:type="menu:PopupMenu" xmi:id="_4VpZwNSmEeG-a6zBTyJ-wg" elementId="org.eclipse.ui.navigator.ProjectExplorer#PopupMenu">
            <tags>menuContribution:popup</tags>
            <tags>popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu</tags>
          </menus>
          <toolbar xmi:id="_4UXAUdSmEeG-a6zBTyJ-wg" elementId="org.eclipse.ui.navigator.ProjectExplorer"/>
        </sharedElements>
        <trimBars xmi:id="_VOV6ANTAEeGTY-uOtVc6Mg" elementId="org.eclipse.ui.main.toolbar"/>
        <trimBars xmi:id="_VP1HwNTAEeGTY-uOtVc6Mg" elementId="org.eclipse.ui.trim.status" side="Bottom">
          <children xsi:type="menu:ToolControl" xmi:id="_VP1u0NTAEeGTY-uOtVc6Mg" elementId="org.eclipse.ui.StatusLine" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.StandardTrim">
            <tags>stretch</tags>
          </children>
          <children xsi:type="menu:ToolControl" xmi:id="_VQKe8NTAEeGTY-uOtVc6Mg" elementId="org.eclipse.ui.HeapStatus" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.StandardTrim"/>
          <children xsi:type="menu:ToolControl" xmi:id="_VQRMoNTAEeGTY-uOtVc6Mg" elementId="org.eclipse.ui.ProgressBar" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.StandardTrim"/>
        </trimBars>
      </children>
      <bindingTables xmi:id="_VnmafNSzEeGBn6dQ9VPexA" bindingContext="_VnmacdSzEeGBn6dQ9VPexA"/>
      <rootContext xmi:id="_VnmacdSzEeGBn6dQ9VPexA" elementId="org.eclipse.ui.contexts.dialogAndWindow" name="In Dialog and Windows">
        <children xmi:id="_VnmactSzEeGBn6dQ9VPexA" elementId="org.eclipse.ui.contexts.window" name="In Windows"/>
        <children xmi:id="_Vnmac9SzEeGBn6dQ9VPexA" elementId="org.eclipse.ui.contexts.dialog" name="In Dialogs"/>
      </rootContext>
      <descriptors xmi:id="_9E9jYNS4EeGBn6dQ9VPexA" elementId="org.eclipse.ui.navigator.ProjectExplorer" label="Project Explorer" iconURI="platform:/plugin/org.eclipse.ui.navigator.resources//icons/full/eview16/resource_persp.gif" category="org.eclipse.e4.primaryNavigationStack" closeable="true" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView">
        <tags>View</tags>
        <tags>categoryTag:General</tags>
      </descriptors>
      <descriptors xmi:id="_W6yT4NSjEeGgKvWHVYtRxQ" elementId="org.eclipse.ui.console.ConsoleView" label="Console" iconURI="platform:/plugin/org.eclipse.ui.console//icons/full/cview16/console_view.gif" allowMultiple="true" category="org.eclipse.e4.secondaryDataStack" closeable="true" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView">
        <tags>View</tags>
        <tags>categoryTag:General</tags>
      </descriptors>
      <descriptors xmi:id="_W6ziANSjEeGgKvWHVYtRxQ" elementId="org.eclipse.ui.views.ProgressView" label="Progress" iconURI="platform:/plugin/org.eclipse.ui.ide//icons/full/eview16/pview.gif" category="org.eclipse.e4.secondaryDataStack" closeable="true" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView">
        <tags>View</tags>
        <tags>categoryTag:General</tags>
      </descriptors>
      <descriptors xmi:id="_W63zcdSjEeGgKvWHVYtRxQ" elementId="org.eclipse.ui.views.PropertySheet" label="Properties" iconURI="platform:/plugin/org.eclipse.ui.views//icons/full/eview16/prop_ps.gif" allowMultiple="true" category="org.eclipse.e4.secondaryDataStack" closeable="true" contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView">
        <tags>View</tags>
        <tags>categoryTag:General</tags>
      </descriptors>
      <addons xmi:id="_VnmadNSzEeGBn6dQ9VPexA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
      <addons xmi:id="_VnmaddSzEeGBn6dQ9VPexA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
      <addons xmi:id="_VnmadtSzEeGBn6dQ9VPexA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
      <addons xmi:id="_Vnmad9SzEeGBn6dQ9VPexA" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/>
      <addons xmi:id="_VnmaeNSzEeGBn6dQ9VPexA" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/>
      <addons xmi:id="_VnmaedSzEeGBn6dQ9VPexA" elementId="org.eclipse.e4.ui.workbench.bindings.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.workbench.swt.util.BindingProcessingAddon"/>
    </application:Application>
    
  10. Understand a basic Application Window layout This definition does a lot of small things. Technically, a few additional namespaces are made available to the application:Application element to use some of the more advanced features. Besides some key binding handlers, the main changes are: shared elements for the main window which define some kind of placeholders for UI contributions. These placeholders are used in the definition of the main window.e4 Application Model of the Main Window using a Project Explorer and Editor Area and a Properties ViewThe Main Window defines Controlswhich are all the parts a user can interact with.
    1. It’s main children is a Perspective (also set as the main perspective of that window) that contains two PartSashContainers.
    2. A PartSashContainer splits the window into several areas (one area for each of its child elements) that have an adjustable width or height, depending on the orientation of the PartSashContainer.
    3. A PartStack is an area where several views can be stacked on top of each other, the different views on such a stack that can all be accessed using tabs at the top of the PartStack as we know it from the Eclipse IDE.
    4. The Placeholders refer to the Shared Elements that we defined as well.
    5. In addition we defined TrimBars, one for the main menu and one for the status bar the bottom for which we also define some default contents such as a progress indicator.
    6. The Shared Elements themselves are where the magic lies. For instance, the Project Explorer is defined by a shared element that defines a Part with the elementId="org.eclipse.ui.navigator.ProjectExplorer" that is made available by the Compatiblity Layer, defined at the URI contributionURI="bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView"
  11. To run the new application, we need a few more plugins that provide the code for the Project Explorer etc. Open the plugin.xml of your RCP plugin (test.rcp) and add the following plugins to its dependencies
    1. org.eclipse.ui.views
    2. org.eclipse.ui.navigator
    3. org.eclipse.ui.navigator.resources

    When you run the application, you should now see the following window.
    Eclipse e4 RCP application with Project Explorer and Properties view
    Notes:

    1. You may have to add more Required Plugins to your launch configuration.
    2. You may have to delete the file ${runtime-workspace}/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi in the runtime-workspace used by your application. This file is created during startup from the Application.e4xmi and after that is used to remember the layout of the window etc. Changes in Application.e4xmi are not copied to the workbench.xmi file.
  12. Last Step: Enable the workspace resources. In the current application, you will not be able to see and use workspace resources such as projects and files. To actually use them, we need to initialize the IDE workspace of Eclipse. In the ApplicationWorkbenchAdvisor.java (generated by the Hello RCP in package test.rcp), override the initialize(...) method (taken from stackoverflow.com)
    ...
    import org.eclipse.core.runtime.Platform;
    import org.eclipse.jface.resource.ImageDescriptor;
    import org.eclipse.ui.ide.IDE;
    import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
    import org.osgi.framework.Bundle;
    ...
    
    @Override
    public void initialize(IWorkbenchConfigurer configurer) {
    	super.initialize(configurer);
    	...
    	// inserted: register workbench adapters
    	IDE.registerAdapters();
    
    	// inserted: register images for rendering explorer view
    	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);
    }
    

    If you do not have any ApplicationWorkbenchAdvisor.java, your Eclipse RCP is probably not built on the Eclipse 3.X framework. Use the Hello RCP template to get a basic structure of your application, including this class, or consult an Eclipse 3.X RCP tutorial. Finally, add plugin org.eclipse.ui.ide to the dependencies of your RCP plugin project in the plugin.xml. The application should now look like this:
    Eclipse e4 RCP application with project explorer, text editor and properties view

Done. You can now extend your application through code as well as through the e4 application model and have access to the Eclipse 3.x views, including other views like the Problems View or the Error Log.

About these ads

22 thoughts on “tutorial : eclipse rcp e4 with 3.x views like project explorer, properties, etc.

  1. Great article, thank you for writing about Eclipse 4. I have a question to your statement about the Eclipse 4 application model editor (As the current editor for the Application.e4xmi has some limitations), which limitation do you see, we can try to fix them.

  2. Hi Ravi,
    It is a very interesting article!!
    After finishing it, I could add the Console, too.
    However, I don’t know how to use the Project Navigator and Console, or even how to add a simple customized View.
    I tried adding simple view as Lars teaches in Eclipse 3 and 4 tutorials, but it is not working over the project I created following your tutorial: “eclipse rcp e4 with 3.x views …”
    Please, could you give just more few steps on how to add a simple view or just how to do a simple thing over the Project Navigator you added?

    Thanks,
    Vítor Moscon

  3. Whoa, now that I’d basically given up hope (and had accomodated myself with the full platform, meh), I stumble across this.
    Great article.

  4. You really make it seem so easy with your presentation but I find
    this matter to be actually something that I think I would never understand.
    It seems too complex and extremely broad for me.
    I’m looking forward for your next post, I will try to get the hang of it!

  5. Thanks for the great information. I am able to now get the eclipse3 Properties VIew to show up in my E4 application (well, now e3 w/ e4 model application).

    However, I am not able to get the Properties View to see my selected items that implement IPropertySource. So nothing shows up in the Properties View. I suspect this is because the selection model has changed between E3 and E4.

    In E3 I would have done something like:
    .getSite().setSelectionProvider(viewer);
    to get selection events to start firing and the Properties View would have seen these.

    In E4 you add yourself to the viewer as a selection change listener and then in the handler you tell the E4 ESelectionService that something has changed selection.
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {
    public void selectionChanged(SelectionChangedEvent event) {
    IStructuredSelection selection = (IStructuredSelection) event.getSelection();
    // set the selection to the service
    selectionService.setSelection(
    selection.size() == 1 ? selection.getFirstElement() : selection.toArray());
    }
    });

    My guess is that the E3 Properties View doesn’t know anything about this ESelectionService and I am not sure if there is something to ‘tweak’ in the CompatibilityLayer that is used in this demo. Or is there some way to still get the old ViewPart and use the E3 selection service.

    Thanks,
    kable

  6. Fantastic beat ! I would like to apprentice while you amend your site, how can
    i subscribe for a blog site? The account aided me a acceptable deal.
    I had been a little bit acquainted of this your broadcast offered bright clear idea

  7. I just want to say that the last 3 – obviously spam – comments (from April 18-23) are absolutely hilarious :).

    Also, thanks Dirk for very useful tutorial.

  8. Its like you read my mind! You seem to know a lot about
    this, like you wrote the book in it or something.
    I think that you can do with some pics to drive the message home a little bit, but other than that, this is magnificent blog.
    A great read. I’ll definitely be back.

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 )

Connecting to %s