• home
  • forum
  • my
  • kt
  • download
  • Create your own Eclipse plug-in template

    Author: 2009-04-24 10:03:33 From:

    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.

    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.



    Back to top


    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);
        ...
    }
    




    Back to top


    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



    Back to top


    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.

    discuss this topic to forum

    relation tutorial

    No information

    Category

      Administration (17)
      Editing Files (5)
      Getting Started (13)
      Installation (10)
      Linux and other OSs (15)
      Miscellaneous (17)
      Networking (11)
      Security (12)
      Shells and Utilities (17)
      System Monitoring (8)
      Troubleshooting (1)
      X Windows (6)

    New

    Hot