Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Create your own Eclipse plug-in template

Customize an existing template to address specific requirements

Jie Tang (jietang@cn.ibm.com), Software Engineer, IBM China
Jie Tang
Jie Tang is a software engineer at IBM China Systems and Technology Laboratories and focuses on system management software. He is currently working on the IBM Director Configuration Manager project. He is also interested in open source projects.
Li Li Lin (linlili@cn.ibm.com), Software Engineer, IBM China
Li Li Lin
Li Li Lin is a software engineer at IBM Director focusing on OSGI-related development. She is proficient in developing plug-ins and has extensive experience with Web-based projects.

Summary:  Default plug-in templates in Eclipse are useful as long as they meet users' needs. When a specified requirement is beyond the scope of a default template, it is necessary to customize a template. This article offers insight into how to customize a plug-in project template in Eclipse, elaborates on multisection implementation and control within templates, introduces UI component customization methods to improve usability, illustrates a way to add input validation function on the UI side, and explains how to organize the directory structure of plug-in project automatically.

Date:  22 Dec 2008
Level:  Intermediate
Also available in:   Japanese  Vietnamese

Activity:  22837 views
Comments:  

If you have created a plug-in project in Eclipse before, you are familiar with the established plug-in project templates, which provide a convenient starting place for new projects. The existing plug-in templates can save a lot of time, but they are not omnipotent.

A challenge to using them is finding the template that satisfies the users' requirements. But templates offer only a certain number of functions, and users' requirements are diverse and almost impossible to foresee perfectly for those who created the templates. Customizing templates is a smart way to give users the plug-ins they need without writing them from scratch.

In this article, learn:

  • How to customize plug-in project template in Eclipse.
  • Advanced characteristics of templates, such as multisection implementation and control, UI component customization, and validation.
  • Tools to organize a project directory structure automatically.

Prerequisites

This article is written for Java™ technology developers familiar with Eclipse and interested in building plug-ins. It assumes a basic understanding of plug-ins and Eclipse-based development tools in general. To build the example plug-ins, you need a computer with an Eclipse installation (V3.4 or later) and a current Java Runtime Environment (JRE).

The work here is based on the developerWorks article "Building templates with the Eclipse Plug-in Development Environment." If you are new to plug-in templates, we suggest you start with that article, which introduces how to create a template. Because that article is introductory, the template it presents lacks the features we offer here, which include the following.

Multisection implementation and control
Generally, a section of a plug-in template is defined as cohesive functional module that contains highly interdependent files established or generated based on users' input. Files under a section will either be replicated into a destination project altogether or not at all. A user can define a section as required or optional. Files under the required section must be included into a plug-in project, while those under the optional section should be copied upon choice. This is useful when a plug-in template offers a function's super-set, but a certain project only needs a subset.
UI component customization
Eclipse provides several default UI components for a plug-in project template. These basic UI components offer limited functions. To improve usability and functionality, we sometimes need to customize complex components.
Input validation function
It increases data validation control.
Organize the directory structure of plug-in project automatically
Resources in plug-in project can be organized into a specific directory using a template. It can save manual effort.

These extended features make a plug-in template more scalable, usable, and efficient. In the following sections, we present a sample template that uses all these features.


Sample case study: In-depth discussion on a plug-in template

Assume a group of plug-in projects are needed. They are used to construct various Eclipse perspectives, like a Java perspective and a Web perspective. One project is for one perspective development. Each perspective can have several views. Every view has relevant resources, such as image and auto-generated Java source files, need to be copied into its project. The number of views in a perspective and the name of each view are determined by the individual perspective.

Customizing a plug-in template is a good way to generate these destination projects.

Create a simple template

To start, create a new plug-in project (File > New > Project > Plug-in Project). Be sure to select the This plug-in will make contribution to the UI checkbox. This is because destination projects in this sample are for perspective development, which will use the UI. Once the new project is created, a template wizard extension extending org.eclipse.pde.ui.plugin.Content should also be added into plugin.xml.

New feature A: Multisection implementation and control

When we look at the above case closely, we discover an issue in customizing the template. Since the number of views for each perspective is alterable, the relevant resources are unable to be generated and copied into its destination project until the number is given.

To address this issue, we consider two solutions. A common method is to create one template for each perspective category where all perspectives of identical view number are assembled. The alternative method is more efficient and advanced. A single template is created for all perspective categories. The linkage between views and perspective is managed by section control.

Add extensions for the perspective and view sections

In this sample, we separate all resources into two sections. We use the perspective section to manage perspective resources and use the view section to manage view resources. If a user wants a perspective with no views, none of the view resources will be replicated into the corresponding project. Likewise, if a user wants perspective with nine views, nine views will be registered into their perspectives, and view sources will be iteratively generated and copied into its destination project.

To generate these two sections, we need to add extensions in the Extensions tab of the Plug-in Manifest Editor.


Figure 1. Extensions tab — Perspective section
Extensions tab –- Perspective section


Figure 2. Extensions tab — View section
Extensions tab -– View section

Section implementation

Figure 3 shows the template project structure. Five new files (SampleWizard.java, PerspectiveSection.java, ViewSection.java, $perspectiveClassName$.java, and $viewClassName$.java) are created in this sample. They constitute the main part of the project.


Figure 3. Template project structure
Template project structure

PerspectiveSection and ViewSection are subclasses of OptionTemplateSection, which is used to represent a section of a template wizard. They have three main functions: to create a UI for the template, to hold variables inputted from the UI, and to update the plug-in model. Table 1 shows the methods description of the section class.


Table 1. Section class methods description
Method nameFunction description
initializeFieldsInitialize options on the wizard page by using input parameters. Some options may depend on the user's selection in the previous steps of the wizard.
addPagesAdd template-related pages to the wizard.
getStringOptionGet the option name.
getSectionIdReturn the section ID.
updateModelAdd the required entries into plug-in model.

$perspectiveClassName$.java and $viewClassName$.java are template files that will be auto-translated into Java source files of the destination project. The template files are very simple in this sample. We just create a list for each view, then add these views into the perspective.

Next is to include section control into the wizard behavior. The SampleWizard class is a subclass of NewPluginTemplateWizard, which is used as a wizard template for the plug-in. We can allocate the specified section to the destination plug-in project via the SampleWizard class. The performFinish method inherits from the super-class. It can be used to perform special finish processing in a wizard, including looping through template sections and executing them sequentially to generate files for destination project. Listing 1 shows how sections are registered into a wizard, and the main actions in the performFinish method.


Listing 1. SampleWizard.java

//register all related sections in wizard
public ITemplateSection[] createTemplateSections() {
    return new ITemplateSection[] {
        new PerspectiveSection(),
        new ViewSection()
    };
}
public boolean performFinish(final IProject project, IPluginModelBase model,
            IProgressMonitor monitor) {
    ...
    ITemplateSection[] sections = super.getTemplateSections();
    //monitor finish action in this wizard
    monitor.beginTask("perform finish", sections.length);
    ...
    //get sections
    for (int i = 0; i <sections.length; i++) {
        if (sections[i].getClass().equals(PerspectiveSection.class)) {
            perspectiveSection = (PerspectiveSection) sections[i];
        } else if (sections[i].getClass().equals(ViewSection.class)) {
            viewSection = (ViewSection) sections[i];
        }
    }
    ...
    //set variables to sections and manage sections
    ...
    viewSection.setViewClassName(values[j]);
    viewSection.setSourcePath(sourceFolderName);
    viewSection.execute(project, model, new SubProgressMonitor(monitor, 1));
    
    perspectiveSection.setSourcePath(sourceFolderName);
    perspectiveSection.setViewNames(viewNames);
    perspectiveSection.execute(project, model, new SubProgressMonitor(monitor, 1));
}

New feature B: UI component customization

As mentioned, a perspective can have as many views the user desires, and the name of each view can be set by the user. To collect all views in a perspective, we design an input panel, shown below. It has a View Class Name field and a View List field. The user can input the view class name and add it into the view list by clicking the Add button. Likewise, the user can also remove a view using the Remove button.


Figure 4. Customized template option
Customized template option

To create this, ViewOption class, which extends TemplateOption, is added into the template project (see Figure 3). We use it to set UI components and store users' inputs. Listing 2 shows how to customize a UI component with a view list, plus two buttons.


Listing 2. ViewOption.java

//add UI components in this panel
public void createControl(Composite parent, int span) {
    ...
    //create View List
    listLabel = new Label(parent, SWT.LEFT);
    listLabel.setText("View List:");
    listViewerField = new ListViewer(parent);
    listField = (List) listViewerField.getControl();
    GridData listGridData = new GridData(GridData.FILL_HORIZONTAL);
    listGridData.heightHint = 100;
    listField.setLayoutData(listGridData);
...
    //create add button
    addButton = new Button(parent, SWT.PUSH);
    addButton.setText("Add");
    ...
    addButton.setLayoutData(addBtnData);
    addButton.addSelectionListener(...);

    //create remove button
    removeButton = new Button(parent, SWT.PUSH);
    ...
    removeButton.addSelectionListener(...);
}


New feature C: Input-validation function

The input-validation function refers to a process of validating all users' inputs before using them. The input-validation function is absolutely critical to application security. In our sample, we define a validation rule: For all views in a perspective, view class name must be unique. If this rule is violated, an error message will be displayed on the top of the panel.


Figure 5. Validate customized template option
Validate customized template option

The input-validation function can be implemented by calling the validateOptions method in the corresponding section class. This method inherits from the super-class, and we can overwrite it to perform our own validation function. Listing 3 shows the validateOptions method in our sample.


Listing 3. validateOptions method in ViewSection.java
    
public void validateOptions(TemplateOption source) {
    this.getPage(0).setErrorMessage(null);
    ViewOption viewOption = (ViewOption) source;
    Text textField = viewOption.getTextField();
    List listField = viewOption.getListField();
    String[] items = listField.getItems();
    if (items != null && items.length > 0) {
        //validation rule check
        for (int i = 0; i < items.length; i++) {
            if (items[i].equals(textField.getText())) {
                this.getPage(0).setErrorMessage("Class name '" 
                    + textField.getText() 
                    + "' already exists in View List.");
                break;
            }
        }
    }
}


New feature D: Organize the directory structure of a plug-in project automatically

One of our goals is to let the template organize directory structure for destination plug-in projects automatically. We implement this with three steps:

  1. Store the directory structure of the destination project using variables.
  2. Write an Ant script, which will be used to create target directory structure and assign resources into right directories.
  3. Add IResourceChangeListener to monitor the workspace of the template. Trigger the Ant script execution once section files' generation is completed.

Implementation

  • To simplify, we assume all Java files are copied into one package, which use the same name as the project name. For instance, if a project is named com.ibm.template, all Java files will be in the package com.ibm.template.This discussion is beyond the scope of this article. See "Building templates with the Eclipse Plug-in Development Environment" for details.
  • Listing 4 shows the Ant script we use in this sample. It has three targets. The first target creates a directory structure based on the source path and the package path. The second one copies all Java files to the correct directory. The last one removes this script file from the new plug-in project.
  • Add IResourceChangeListener into performFinish method of SampleWizard class. Listing 5 shows the implementation of this listener.

Listing 4. CreatePackage.xml

<?xml version="1.0"?>
<project name="template project" default="clean" basedir=".">
    <property name="package" value=".\$sourcePath$\$packagePath$"></property>
    <target name="create">
        <mkdir dir="$dollarMark${package}"/>
    </target>
    <target name="move" depends="create">
        <move todir="$dollarMark${package}">
            <fileset dir=".">
                <include name="*.java"/>
            </fileset>
        </move>
    </target>
    <target name="clean" depends="move">
        <delete dir=".">
            <include name="CreatePackage.xml"/>
        </delete>
    </target>
</project>



Listing 5. SampleWizard.java — Listener

public boolean performFinish(final IProject project, IPluginModelBase model,
IProgressMonitor monitor) {
    ...
    //get workspace
    final IWorkspace workspace = ResourcesPlugin.getWorkspace();
    //get Ant file
    String antFilePath = "CreatePackage.xml";
    final IFile file = project.getFile(antFilePath);
    //add Listener to monitor resource changing
    IResourceChangeListener listener = new IResourceChangeListener() {
        public void resourceChanged(IResourceChangeEvent event) {
            try {
                if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
                    IResourceDelta rootDelta = event.getDelta();
                    IPath filePath = file.getFullPath();
                    IResourceDelta targetDelta = rootDelta.findMember(filePath);
                    if (targetDelta != null) {
                        URI uri = file.getLocationURI();
                        File antFile = new File(uri);
                        //run Ant script                        
                        Project project = new Project();
                        project.fireBuildStarted();
                        project.init();
                        ProjectHelper helper = ProjectHelper.getProjectHelper();
                        helper.parse(project, antFile);
                        project.executeTarget(project.getDefaultTarget());
                        project.fireBuildFinished(null);
                        workspace.removeResourceChangeListener(this);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    workspace.addResourceChangeListener(listener);
    ...
}



Using the template

Once we create a new plug-in project, we need to refresh the project. Right-click the project and select the Refresh menu item. That's because our Ant script is executed after the project generation. We need to refresh the project in the Eclipse IDE manually. Listing 6 is a plug-in project generated through the sample template discussed in "Sample case study: In-depth discussion on a plug-in template."


Figure 6. New project structure
New project structure

You need to export this new project to the [eclipse_home]\plugins directory, then restart Eclipse with the -clean parameter. After Eclipse starts, check to see that our perspective has been added into the perspective list (see in Figure 7). Select myplugin perspective, then click OK. This perspective will open.


Figure 7. Perspective list
Perspective list


Conclusion

Through this article, you should have further understanding of Eclipse plug-in template. You learned how to create a customized input component, how to control the generation of template files, and how to use one template to generate plug-in projects with different directory structures. By taking advantage of these template features, you will find it is easier to create a plug-in project.



Download

DescriptionNameSizeDownload method
Sample plug-in templateos-eclipse-plugin-templates.zip33KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)

  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.

  • Participate in developerWorks blogs and get involved in the developerWorks community.

About the authors

Jie Tang

Jie Tang is a software engineer at IBM China Systems and Technology Laboratories and focuses on system management software. He is currently working on the IBM Director Configuration Manager project. He is also interested in open source projects.

Li Li Lin

Li Li Lin is a software engineer at IBM Director focusing on OSGI-related development. She is proficient in developing plug-ins and has extensive experience with Web-based projects.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=359371
ArticleTitle=Create your own Eclipse plug-in template
publish-date=12222008
author1-email=jietang@cn.ibm.com
author1-email-cc=
author2-email=linlili@cn.ibm.com
author2-email-cc=