"Excellence through total Moderation" - Cleobulus

Thursday, February 14, 2008

Eclipse RCP Recipes: Creating Custom Eclipse Editors

In this blog entry I describe the model and basic steps towards creating a custom eclipse editor that is not necessarily bound to files or resources but a general object model. In this example we will describe the creation of a tree table editor.

The basic components needed for the editor’s development are:

  1. The class implementing the editor part (IEditorPart interface). In our example this class takes care of initialising the editor by constructing the table tree from a given object model.

  2. The class implementing the editor’s input (IEditorInput interface). This class will provide the editor with the necessary input data, as in the object model data, which will be displayed by the editor.

  3. The action delegate that binds the editor to the UI menu (IWorkbenchWindowActionDelegate interface).

  4. The object model.

  5. In case of a tree/tabular view such as the one in the example, we will need a content provider to provide the object model to the UI view elements and a label provider that will generate the correct UI output from the object model.

In this section I assume that the reader is familiar with the eclipse mechanisms of content and label providers for tree and table viewers.

  1. Create the Editor Part

    1. The first step is to extend the eclipse editors extension that will provide us with the basic skeleton for the editor part. In your plugin's MANIFEST.MF file editor, select the extensions page and add an org.eclipse.ui.editors extension (don’t use any templates just select and click Finsh).

    2. Then right click on that extension and go New->editor. Fill the fields:

      1. id = the id of the editor. You need it so that the editor can be identified by the action that will attempt to open it.

      2. name = the name of the editor in a human readable string. This will be shown on the editor tab.

      3. icon = the icon that will show on the editor’s tab.

      4. class = the editor’s implementing class. The extension point forces the implementation of the IEditorPart interface which offers the basic method declarations. However, you will normally be either subclassing the EditorPart or the MultiPageEditorPart abstract base classes that provide the basic functionality as well. In our example, since we are only using one page for our table tree we extend the EditorPart.

    3. Create the editor’s opening action

      1. We will add another extension to the plugin, in order to make our editor action that will open the editor from the menu. Once again at the extensions page of the MANIFEST.MF editor add the org.eclipse.ui.actionSets. Righ-click on it and go New->actionSet. On this set of actions you will need again to provide a unique id, a human readable label string, as well as set the visibility to true and providing a short description.

      2. Now we will add a submenu on the UI’s menubar. Right click on our new actionSet and go New->menu. Again give it an id and a label that will the text showing on the UI menubar. In the path field put “additions”. This will add it to the point of the menubar where new items can be added.

      3. Finally, we create our editor opening action. Right click on the actionSet, NOT the menu and go New->action. Besides the id and the UI visible label you will need to complete some other fields:

        1. menubarPath = this is the place where the action will be placed on the menu bar. Since we created our own submenu previously we would want to put it there. Thus for this field put the menu’s “[id]/content”.

        2. toolbarPath = this is the place you would put the action if you wanted to add it in the toolbar. Put it under “Normal/additions”.

        3. icon = the icon that will be shown both in the submenu option and the tool bar.

        4. class = the class that implements the action. In our case we will be implementing the IWorkbenchWindowActionDelegate interface.

  2. Create the editor’s input. Here we will be creating the class for the editor’s input that implements the EditorPart.

  3. Implement the action. In our action class we are mainly interested in the init(…) and the run(…) methods. The init method which initialises the action passes the workbench window which we will need so that we can extract the active page which is responsible for opening editors.

    1. In the init(…) simply store the window parameter as a field.

    2. In the run(…) method is where the magic happens, when the user selects the action from the UI menu. Here we create a new editor input object and pass it as a parameter to the active page’s openEditor(…) method along with the editor’s ID:

    IWorkbenchPage page = window.getActivePage();
    theEditorInput input = new theEditorInput();
    try {
    page.openEditor(input, theEditor.ID);
    } catch (PartInitException e) {
    LOGGER.error("Problem initialising the Editor");

  4. Implement the editor input. We are mainly interested here in implementing the getAdapter(…) method which is the method that the editor calls to get its input. The method gets as a parameter the class of the object that will be used as input for the editor, so we need to check that the object we pass is of the same class.

  5. Implement the editor part. Finally we come to our main class, the editor part. Here we are interested in the init(…) and the createPartControl(…) methods.

    1. The init(…) initialisation method is what basically gets called as a result of the propagation of the action’s run method that calls the page’s openEditor(…). Here we need to call the EditorPart superclass setSite(…) and setInput(…) to have our Editor initialise properly. We can then get the object model data by calling the getAdapter(…) method (seen above) from the editor input object parameter.

    2. The createPartControl(…) is called to construct and display the editor’s contents. Given that we have stored the object model data acquired from the init(…) method, inside the createPartControl(…) we can then do:

parent.setLayout(new FillLayout());
tableParent = parent;

... where createTable() is our method that initializes the table to be displayed by the editor, setting its content and label providers accordingly.

No comments: