How to write Eclipse Plugin?

SHARE & COMMENT :

This article will guide you in creating Eclipse Plugins using the Eclipse Plugin Development Environment (PDE). Because the Plugin Development Architecture is vast, this article will only provide brief information about the various components that fits into the PDE. It starts off in creating a Simple Plugin and they will try to explain the various pieces involved in the Plugin Development. More specifically this article will show how to create a View based Plugin, an Action based Plugin and a Preference-based Plugin.

1. Creating Views and Categories

Views occupy majority of the portion in any IDE and in Eclipse they generally falls into some Category. For example, there are Views like ‘Declaration’, ‘Hierarchy’, ‘Package Explorer’, and ‘JavaDoc’ that falls under a category called ‘Java’. This can be seen by going to Window–>Show View–>Other. When you go there you can see a list of Categories like ‘General’, ‘Ant’, ‘Cheat Sheats’, ‘CVS’, ‘Debug’, ‘Help’, ‘Java’ and so on. These are called View Categories. Once after expanding a particular Category you can see a group of Views under that Category. So Category, in general, acts as a Container for holding logically similar type of Views.

1.1) Creating a View within a Category

Let us see how to create one such Custom Category having some Views defined within it. Let us name the category as ‘Organization’ having various Views like ‘Employee’ and ‘Department’.
Follow the steps to create a new Plugin Project in Eclipse representing User-defined Views.

  1. Choose File–>New–>Project, expand the Plug-in Development Folder and then choose ‘Plug-in Project’ and click Next.
  2. For Project Name, give net.javabeat.eclipse.plugins.organization and click Next.
  3. Then comes the ‘New Plug-in Project’ Page where you can configure the various properties of the plug-in that you are going to create. Ensure that the following values are filled in the respective columns for the ‘Plug-in Properties’.
    • Plug-in ID: net.javabeat.eclipse.plugins.organization
    • Plugin Version: 1.0.0
    • Plug-in Name: Organization Plug-in
    • Plug-in Provider: javabeat.net
    • Classpath: organization.jar
    • In the Plug-in Options panel, rename the Activator class to net.javabeat.eclipse.plugins.organizations.OrganizationActivator. Leave the remaining defaults and click Next.
    • Choose the Template ‘Plug-in with a View’ in the Available Templates and click ‘Next’.
    • Ensure that the following values are given in the respective Text Fields in the Main View Settings.
      • Java Package Name: net.javabeat.eclipse.plugins.countries.views
      • View Class Name: OrganizationView
      • View Name: Employee
      • View Category ID: net.javabeat.eclipse.plugins.organization
      • View Category Name: Organization
    • Un-check the ‘Add the view to the resource perspective’ check-box and click Next.
    • Click Next and un-check all the View Features. For this simple View, we don’t necessarily need all these features.
    • When you click the Finish Button, Eclipse will prompt you to switch to ‘Plug-in Development Perspective’. Check ‘Remember my decision’ check-box and press yes.

Browse to OrganizationView.java which is available under 'net.javabeat.eclipse.plugins.organization.views' package and search for the method 'getElements(Object)' in the 'ViewContentProvider' class. This is the method that will called to return the objects for decorating the View in consideration. By default, this method returns a String Array containing ‘One’, ‘Two’ and ‘Three’. Modify the String Array such that it is returning something like return new String[] {“Harry”, “David”};
To make the names more meaningful, double click the plugin.xml file and choose the plugin.xml tab in the active Editor. There you can see the View definition for the Employee. Replace the value of the attribute ‘id’ with 'net.javabeat.eclipse.plugins.organization.views.EmployeeView'.
To run the Organization Plugin Application that you have just developed, right-click the Project, Go to Run As and then choose Eclipse Application. Eclipse will now create a Default Work-Bench pointing to ‘runtime-EclipseApplication’ directory which is created in the same level as the current work-area directory. In the new Eclipse Workbench, Go to Window Menu, and then choose Show View–>Other where you can find a Category by name ‘Organization’. Expand it to see the View called ‘Employee’ that we just created before. Click the view to see the View get attached with the existing list of Views.

1.2) Creating Multiple Views

In this section, let us expand the above example by providing support to create Multiple Views. Let us create another View called ‘Department’ within the Organization Category. To do this, carry out the following steps.

  1. Double-click the plugin.xml and to bring the editor in front. You can see a series of tabs attached to this editor. Click on the plugin.xml tab.
  2. To add another View called ‘Department’ under the ‘Organization’ Category, simply copy the view definition (given below) and paste it below the exiting View Definition, i.e Employee View, in the Xml file.

Now the plugin.xml file will look like this, plugin.xml
Note that the name of the New View is ‘Department’ and the corresponding View Id is 'net.javabeat.eclipse.plugins.countries.views.DepartmentView', though the class name for this view is still pointing to 'net.javabeat.eclipse.plugins.organization.views.OrganizationView'. Since we are re-using the same class for both the Employee View as well as the Department View, make the following changes in the OrganizationView.java file so that Employee View and Department View looks different in terms of appearance. Navigate to the getElements(Object) method found in the inner class ViewContentProvider and add the following code.

public Object[] getElements(Object parent) {

    if (parent instanceof IViewSite){
        IViewSite view = (IViewSite)parent;
        String viewId = view.getId();

        if (viewId.equals(EMPLOYEE_VIEW_ID)){
            return new String[]{"Harry", "David"};
        }else if (viewId.equals(DEPARTMENT_VIEW_ID)){
            return new String[]{"Admin", "Travel"};
        }
    }
    return null;
}

Don’t forget to declare the variables EMPLOYEE_VIEW_ID and DEPARTMENT_VIEW_ID which are pointing to their respective View Identifiers as being configured in the plugin.xml file.

private static final String EMPLOYEE_VIEW_ID =
 "net.javabeat.eclipse.plugins.organization.views.EmployeeView";

private static final String DEPARTMENT_VIEW_ID =
 "net.javabeat.eclipse.plugins.organization.views.DepartmentView";

Run the Application, then you will something like the one in the following figure.
Employee and Department Views

2) What we have done so far?

In the previous section, we developed a Simple View Plugin within a Category. Now, let us briefly see the Various Classes and Configuration Files that are involved in the Developmental Process.

2.1) Plugins

Most of the things we see in Eclipse Environment are Plugins and they form the core Components in Eclipse Environment. A Plugin is represented by org.eclipse.core.runtime.Plugin class. Since Eclipse Plugins started to conform with OSGI Model (starting from 3.0), all Plugins implemented by the org.osgi.framework.BundleActivator interface which provides the Life Cycle Methods like starting and stopping a bundle in the form of start() and stop() methods. The most common variations of the Plugin interface are the User Interface Plugin, Resources Plugin and the Variables Plugin. Customized Views, Dialogs and Preferences Page creation in a Project will mandates the need to the the UI Plugin (represented by org.eclipse.ui.plugin.AbstractUIPlugin). The Resources Plugin (org.eclipse.core.resources.ResourcesPlugin) is used to load and unload any type of Resources being referred in an Application. The Variables Plugin maintains a list of Varaibles like Environment Variables, Path Variables and any User-defined Variables within the Environment.

2.2) Activators

Simply put, this Activator will be the class that will be loaded initially and if you look into the hierarchy of the Activator class (net.javabeat.eclipse.plugins.organization.OrganizationActivator), it extends the AbstractUIPlugin, which tells the Eclipse Run-time that this Plugin is someway related to the Eclipse Platform UI. Note that the method getDefault() will be called by the Eclipse run-time to return the Plugin instance. Since it’s of no meaning to maintain more than one instance of the Plugin class, the Activator class is maintained as a Singleton Class by having a shared static variable of type OrganizationActivator.
OrganizationActivator.java

package net.javabeat.eclipse.plugins.organization;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
* The activator class controls the plug-in life cycle
*/
public class OrganizationActivator extends AbstractUIPlugin {

    // The plug-in ID
    public static final String PLUGIN_ID =
	    "net.javabeat.eclipse.plugins.organization";

    // The shared instance
    private static OrganizationActivator plugin;

    /**
    * The constructor
    */
    public OrganizationActivator() {
        plugin = this;
    }

    /*
    * (non-Javadoc)
    * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(
	* org.osgi.framework.BundleContext)
    */
    public void start(BundleContext context) throws Exception {
        super.start(context);
    }

    /*
    * (non-Javadoc)
    * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(
	* org.osgi.framework.BundleContext)
    */
    public void stop(BundleContext context) throws Exception {
        plugin = null;
        super.stop(context);
    }

    /**
    * Returns the shared instance
    *
    * @return the shared instance
    */
    public static OrganizationActivator getDefault() {
        return plugin;
    }

    /**
    * Returns an image descriptor for the image file at the given
    * plug-in relative path
    *
    * @param path the path
    * @return the image descriptor
    */
    public static ImageDescriptor getImageDescriptor(String path) {
        return imageDescriptorFromPlugin(PLUGIN_ID, path);
    }
}

2.3) Views

Views in Eclipse are represented by 'org.eclipse.ui.part.ViewPart' class which can be sub-classed to create a Customized View along with View Contents. Views tightly integrate with Content Providers and Label Providers. A content Provider which is represented by org.eclipse.jface.viewers.IContentProvider provides the Model Information directly to the View. On the other hand, Label Providers (org.eclipse.jface.viewers.IBaseLabelProvider) associates elements in the View either with Text or Images. For example, a Label Provider may associate a Custom Icon along with a Directory object.
Views are related with Label Providers and Content Providers with the help of setContentProvider() and setLabelProvider() methods. Since we want a return different model values for Employee and Department Views, we have overridden the getElements() method in Content Provider class to return different set of data.

2.4) Plugin Configuration File

Let us analyze the contents of plugin.xml file in this section. All Eclipse Plugins supports the notion of Extension and Extension Points. For example, a vendor who creates a plugin will architect the Plugin in such a way that other Plugins can extend this plugin to add its own additional behaviors. So, Extension Points acts as a mediator between the Existing Plugin and the new Plugin which wants to add new functionalities. Eclipse already comes with a bunch of Extension Points so that we can directly depend on them instead of writing everything from the scratch.
The root element in the plugin.xml in the ‘plugin’ element that represents a Plugin. In our case, since we are going to create a new View, we have the corresponding ‘extension’ tag with the ‘point’ attribute pointing to 'org.eclipse.ui.views'.
plugin.xml
Other than Views, there are so many Extension Points that comes along with Eclipse, to name a few, Perspective Extensions for decorating Custom Perspectives (org.eclipse.ui.perspectiveExtensions), User defined Pop-up Menus (org.eclipse.ui.popupMenus), for creating Preference Pages (org.eclispe.ui.preferencePages), for creating Menus and Toolbar (org.eclipse.ui.actionSets).
Then comes the ‘category’ element which acts as a container for holding multiple Views. The ‘name’ attribute acts as a label and the ‘identifier’ attribute, which is 'net.javabeat.eclipse.plugins.organization', is uniquely used to identify the Organization category.
Views can be created by defining a ‘view’ element. The relationship between the View and a Category is maintained by the ‘category’ attribute. Since we want both the ‘Employee’ and the ‘Department’ Views to be a part of the ‘Organization’ category we
have pointed out the ‘category’ attribute to 'net.javabeat.eclipse.plugins.organization'. Following is the definition for ‘Employee’ and ‘Department’ Views.

3) Creating Menus and Toolbars

In this section, let us put our effort in creating Customized Menus and Toolbars using the Eclipse PDE. For this, let us create a Menu called ‘MS Office’ which has menu items namely ‘MS Word’, ‘MS Excel’ and ‘MS Access’. Users can click any of these menu items to launch the corresponding Application. Without waiting, let us jump directly to start the coding.
Follow the steps to create the new Plugin.

  1. Choose File–>New–>Project, expand the Plug-in Development Folder, choose the Plug-in Project and Click Next.
  2. Give ‘net.javabeat.eclipse.plugins.msofficelauncher’ for the project name and click Next.
  3. Check for the following values in the Plug-in Properties Panel which is in the
  4. Plug-in Content Dialog
  5. Plug-in ID: net.javabeat.eclipse.plugins.msofficelauncher
  6. Plug-in Version: 1.0.0
  7. Plug-in Name: MsOfficelauncher Plug-in
  8. Plug-in Provider: javabeat.net
  9. Classpath: msofficelauncher.jar
  10. Give the Activator class name as ‘net.javabeat.eclipse.plugins.msofficelauncher.MsOfficeLauncher’ and Click Next.
  11. Choose ‘Hello World’ in the ‘Available Templates’ Panel and Click Next.
  12. Name the Action class name as ‘MsOfficeAction’ and press the Finish Button.

Now we want to create a Menu called ‘MS Office’ which has ‘MS Word’, ‘MS Excel’ and ‘MS Access’ as the menu items. To achieve this, do the following steps.

  1. Double-click the MANIFEST.MF file which is the META-INF directory to bring up the Editor.
  2. The editor has a number of tabs arranged in the bottom like ‘Overview’, Dependencies’, … ‘build.properties’. Click the ‘Extensions’ tab where you can see 3 panels namely ‘All Extensions’ (in the left), ‘Extension Details’ (in the right) and ‘Body Text’ in the bottom.
  3. In the ‘All Extension’ Panel, you can see an expandable item by name ‘org.eclipse.ui.actionSets’. Expand this to bring the ‘Sample Action Set (actionSet)’ item and expand it further to see the ‘Sample Menu’.
  4. Select the ‘Sample Action Set(actionSet)’ item, in the ‘Extension Element Details’ panel (right-side), you can see the corresponding properties for the item. Change to label property to ‘MS Office Action Set’ and leave the other default settings.
  5. Click on the ‘Sample Menu (menu)’ item and change the value of the properties ‘id’ and ‘label’ to ‘MsOfficeMenu’ and ‘MS &Office’.
  6. Select the sampleGroup (separator) item which is under ‘MS Office (menu)’ item and change its name to ‘MsOfficeGroup’.
  7. Delete the existing ‘Sample Action (action)’ by pressing the Delete key and add a new Action by the following steps. a). Right-click on the ‘MS Office Action Set (actionSet)’ and then choose New–>Action. It will add a new Action with some default values. Edit the default values with the one that is given below.
  8. id: net.javabeat.eclipse.plugins.msofficelauncher.msWord
  9. label: MS &Word
  10. menubarPath: MsOfficeMenu/MsOfficeGroup
  11. toolbarPath: MsOfficeGroup
  12. icon: icons/sample.gif
  13. tooltip: Microsoft Word Application
  14. class: net.javabeat.eclipse.plugins.msofficelauncher.actions.MsOfficeAction
  15. Add another action by right-clicking the ‘MS Office Action Set (actionSet)’, choosing New–>Action with the following properties.
  16. id: net.javabeat.eclipse.plugins.msofficelauncher.msExcel
  17. label: MS &Excel
  18. menubarPath: MsOfficeMenu/MsOfficeGroup
  19. toolbarPath: MsOfficeGroup
  20. icon: icons/sample.gif
  21. tooltip: Microsoft Excel Application
  22. class: net.javabeat.eclipse.plugins.msofficelauncher.actions.MsOfficeAction
  23. And one more for ‘MS Access’ with the following properties.
  24. id: net.javabeat.eclipse.plugins.msofficelauncher.msAccess
  25. label: MS &Access
  26. menubarPath: MsOfficeMenu/MsOfficeGroup
  27. toolbarPath: MsOfficeGroup
  28. icon: icons/sample.gif
  29. tooltip: Microsoft Access Application
  30. class: net.javabeat.eclipse.plugins.msofficelauncher.actions.MsOfficeAction

Now, go to the MsOfficeAction.java file which is inside the ‘net.javabeat.eclipse.plugins.msofficelauncher.actions’ package and do the following code changes. The changes are in relation with handling Appropriate Events (click of MS Word Item, or MS Excel Item or MS Access Item) and then taking the corresponding Actions (Opening the Application). Jump to MsOfficeAction.run(IAction) method and make the changes as specified below.

public void run(IAction action) {

    String id = action.getId();
    String actionItem = "";
    if (id.equals(MSWORD_ACTION)){
        actionItem = "winword.exe";
    }else if (id.equals(MSEXCEL_ACTION)){
        actionItem = "excel.exe";
    }else if (id.equals(MSACCESS_ACTION)){
        actionItem = "msaccess.exe";
    }

    String fullPath = officeInstallationPath + java.io.File.separator + actionItem;
    ProcessBuilder processBuider = new ProcessBuilder(new String[]{fullPath});
    try{
        processBuider.start();
    }catch (java.io.IOException exception){
        exception.printStackTrace();
    }
}

In the above code, we check for the Item that raised the Event with the help of the Action Id, and then constructs the path of the executable file accordingly. Then we launch the Application by using the Java ProcessBuilder class. For completeness, following is the declaration of the various objects that points to the various Action Identifiers.

private static final String MSWORD_ACTION =
    "net.javabeat.eclipse.plugins.msofficelauncher.msWord";

private static final String MSEXCEL_ACTION =
    "net.javabeat.eclipse.plugins.msofficelauncher.msExcel";

private static final String MSACCESS_ACTION =
    "net.javabeat.eclipse.plugins.msofficelauncher.msAccess";

private static final String officeInstallationPath =
    "C:\\Program Files\\Microsoft Office\\OFFICE11";

Note that the variable 'officeInstallationPath' must point to the installation directory of MS Office Distribution in your machine. To run the Application, right-click the project and choose Run As–>Eclipse Application. A new Eclipse Workbench will launch, where you can see a menu by name ‘MS office’ which is adjacent to the ‘Project’ Menu. Click the menu will bring the menu Items ‘MS Access’, ‘MS Word’ and ‘MS Excel’. Also note the arrangement of the Toolbar buttons having appropriate Tool tips as being configured in the plugin.xml file. Clicking the menu items (or through the Tool Bar) will launch the Appropriate Application in a separate process space.
MSOffice Menu with various Menu Items

4) Creating Preferences

The final section of this article will show you how to create Preferences Page in Eclipse. Preferences usually store Application related or Client related data and it can be accessed through Window–>Preferences. You can see a number of Preference Items like ‘General’, ‘Ant’, … , ‘Team’ etc. These are technically called as Preference Pages in Eclipse Terminology. Carry out the following steps to create a Custom Preference Page in Eclipse.

  1. Click File–>New–>Project, choose Plug-in Project from the folder ‘Plug-in Development’ folder and click ‘Next’.
  2. Enter the project name as ‘net.javabeat.eclipse.plugins.preferences’ and click Next.
  3. Check for the following values in the Plug-in Properties.
    • Plug-in ID: net.javabeat.eclipse.plugins.preferences
    • Plug-in Version: 1.0.0
    • Plug-in Name: Preferences Plug-in
    • Plug-in Provider: javabeat.net
    • Classpath: preferences.jar
    • Rename the Activator class as ‘net.javabeat.eclipse.plugins.preferences.PreferencesActivator’ and click Next.
    • Choose ‘Custom Plug-in wizard’ this time and Click Next.
    • Deselect all the Available Templates by clicking the ‘Deselect All’ button (found in the right side) and then select only the template by name ‘Preference Page’ and click Next.
    • Leave the defaults for the Java Package name, Preference Page Class Name and Preference Page Name and click Finish.

Navigate to ‘SamplePreferencePage’ which is in the 'net.javabeat.eclipse.plugins.preferences.preferences' package. By default, the Wizard creates a number of Field Editors for the Sample Preference Page, which can be found in SamplePreferencePage.createFieldEditors() method. Simply put, a Preference Page View is nothing but a collection of Field Editors. A Field Editor is used to store the User’s Preference Data, like the Home Directory for all Eclipse Projects. There are a number of Pre-defined Field Editors in Eclipse like Boolean Field Editor, Integer Field Editor, String Field Editor, File Field Editor, Directory Field Editor, Color Field Editor etc.
A Field Editor is added to a Preference page by calling the addField() method which is passed a Field Editor Object. Consider the following Code which by default got generated by the PDE.

public void createFieldEditors() {

    addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH,
        "&Directory preference:", getFieldEditorParent()));

    addField(new BooleanFieldEditor(
        PreferenceConstants.P_BOOLEAN, "&An example of a boolean preference",
            getFieldEditorParent()));

    addField(new RadioGroupFieldEditor(PreferenceConstants.P_CHOICE,
        "An example of a multiple-choice preference", 1,
            new String[][] {
			{"&Choice 1", "choice1" },
			{"C&hoice 2", "choice2" }}, getFieldEditorParent()));

    addField(new StringFieldEditor(PreferenceConstants.P_STRING,
	    "A &text preference:", getFieldEditorParent()));
}

A Directory Field Editor as represented by org.eclipse.jface.preference.DirectoryFieldEditor is used to input the Directory name from the User by showing the Browse Directory Dialog. All Field Editor Components generally accept a Unique name along with a Label name. Other than that, they will also accept Editor specific values for construction. By default a Label containing the text, a Text-Field to hold the name of the Directory is created in this case. The next is the Boolean Field Editor that is used to turn-on or turn-off a property. The View for a Boolean Field Editor is shown in the form of a Check-box. Next is the Radio Group Field Editor which presents multiple choices in the form of Radio Buttons. Finally, the String Field Editor is used to accept String based inputs.
Run the Application directly without making any code changes to see how Eclipse PDE simplifies the Development Process. Right-click the project, choose RunAs–>Eclipse Application to see the new Work-bench. Go to Window–>Preferences to see the ‘Sample Preferences’ listed in alphabetical order. To make things interesting, add the following additional Field Editors in the createFieldEditors() method to get a feel over Field Editors.

public void createFieldEditors(){

    ...

    addField(new ColorFieldEditor(
	    "Color", "Choose your favourite Color", getFieldEditorParent()));

    addField(new FontFieldEditor(
	    "Font", "Select a Font", "Eclipse", getFieldEditorParent()));

    addField(new PathEditor(
	    "Path", "Directory Paths", "Choose a Folder", getFieldEditorParent()));

    addField(new ScaleFieldEditor(
	    "Scale", "Adjust the Slider", getFieldEditorParent(), 10, 100, 5, 20));
}

Build the Application and then run the Project as Eclipse Application to see additional Field Editors being populated in the Sample Preferences Page.
Custom Preference Page

5) Conclusion

This article guided you how to create Custom Plugins with ease using the Eclipse PDE. Starting with the Creation of View Plugin, it then went on explaining the concepts related to Plugins like Extensions, Extension Points. Then a deeper look over the various Java files along with the Concepts of Views/Activators and then the Plugin Configuration File is made. Continuing that, creation of ActionSet based Plugins and Preference based Plugins are also given healthier discussion.

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Trackbacks

  1. […] if every time a new plugin was developed for the Eclipse , it had to be refactored to adapt to the use of this new plugin. It would be very laborious and […]

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better