Develop Eclipse Plug-ins Tutorial

64 篇文章 0 订阅
53 篇文章 0 订阅

Eclipse Plug-ins Tutorial

This article describes the creation and deployment of Eclipse plug-ins. The article is based on Eclipse 4.2 (Eclipse Juno) and Java 1.6.


1. Developing Eclipse Plug-ins

A software component in Eclipse is called a plug-in.

The Eclipse IDE allows the developer to extend the IDE functionality via plug-ins. For example you can create new menu entries or new editors via plug-ins.

2. Prerequisites

This tutorial assumes that you are already familiar with using the Eclipse IDE and have experience in developing Java.

3. Tutorial: Hello World Plug-in

We will create a plug-in which contributes a menu entry to the standard Eclipse menu.

Create a new plug-in project called de.vogella.plugin.first viaFileNewProject Plug-inDevelopment Plug-in Project.

Select the Hello, World Command! template and press theFinish button. This should automatically open the Plug-in Development perspective.

Select the file MANIFEST.MF file , right click it on it and selectRun-AsEclipse Application

A new Eclipse workbench starts. This runtime Eclipse has your new menu entry included. If you select this menu entry a message box will be displayed.

4. Contribute a menu to existing Part

4.1. Overview

In this example we will add a new context menu entry to the Package explorer part. The context menu is displayed if the user select a file in the package explorer via a right mouse click. We will offer the option to create a HTML page from a Java source file.

To contribute to an existing menu or toolbar you need to know the corresponding ID. This ID can be found via theMenu Spy. See Eclipse Source Code Guide for details.

4.2. Contribute to package explorer

This tutorial uses Eclipse Commands. See Eclipse Commands Tutorial to learn how to work with commands.

Create a new plug-in project called de.vogella.plugin.htmlconverter. Do not use a template.

Select the Dependencies tab of the file plugin.xml and add the following dependencies to your plug-in.

  • org.eclipse.jdt.core

  • org.eclipse.core.resources

  • org.eclipse.core.runtime

  • org.eclipse.core.resources

  • org.eclipse.core.expressions

Add a command with the ID de.vogella.plugin.htmlconverter.convert and the default handlerde.vogella.plugin.htmlconverter.handler.ConvertHandler to your plug-in.

Add this command to the menu via the extension point org.eclipse.ui.menus and use as the "locationURI"popup:org.eclipse.jdt.ui.PackageExplorer. Set the label to "Create HTML" for this contribution.

The resulting file plugin.xml should look like the following.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
  <extension point="org.eclipse.ui.menus">
    <menuContribution locationURI="popup:org.eclipse.jdt.ui.PackageExplorer">
      <command commandId="de.vogella.plugin.htmlconverter.convert"
        label="Create HTML" style="push">
      </command>
    </menuContribution>
  </extension>
  <extension point="org.eclipse.ui.commands">
    <command defaultHandler="de.vogella.plugin.htmlconverter.handler.ConvertHandler"
      id="de.vogella.plugin.htmlconverter.convert" name="Convert">
    </command>
  </extension>

</plugin> 

Eclipse allows to save additional information for each file. You can use the IResource interface and the setPersistentProperty() andgetPersistentProperty() methods. With these functions you can save Strings on files. We use these functions to save a directory for Java source files which already were exported via HTML.

Create the following ConvertHandler class.

package de.vogella.plugin.htmlconverter.handler;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;

public class ConvertHandler extends AbstractHandler {
  private QualifiedName path = new QualifiedName("html", "path");

  @Override
  public Object execute(ExecutionEvent event) throws ExecutionException {
    Shell shell = HandlerUtil.getActiveShell(event);
    ISelection sel = HandlerUtil.getActiveMenuSelection(event);
    IStructuredSelection selection = (IStructuredSelection) sel;

    Object firstElement = selection.getFirstElement();
    if (firstElement instanceof ICompilationUnit) {
      createOutput(shell, firstElement);

    } else {
      MessageDialog.openInformation(shell, "Info",
          "Please select a Java source file");
    }
    return null;
  }

  private void createOutput(Shell shell, Object firstElement) {
    String directory;
    ICompilationUnit cu = (ICompilationUnit) firstElement;
    IResource res = cu.getResource();
    boolean newDirectory = true;
    directory = getPersistentProperty(res, path);

    if (directory != null && directory.length() > 0) {
      newDirectory = !(MessageDialog.openQuestion(shell, "Question",
          "Use the previous output directory?"));
    }
    if (newDirectory) {
      DirectoryDialog fileDialog = new DirectoryDialog(shell);
      directory = fileDialog.open();

    }
    if (directory != null && directory.length() > 0) {
      setPersistentProperty(res, path, directory);
      write(directory, cu);
    }
  }

  protected String getPersistentProperty(IResource res, QualifiedName qn) {
    try {
      return res.getPersistentProperty(qn);
    } catch (CoreException e) {
      return "";
    }
  }

  protected void setPersistentProperty(IResource res, QualifiedName qn,
      String value) {
    try {
      res.setPersistentProperty(qn, value);
    } catch (CoreException e) {
      e.printStackTrace();
    }
  }

  private void write(String dir, ICompilationUnit cu) {
    try {
      cu.getCorrespondingResource().getName();
      String test = cu.getCorrespondingResource().getName();
      // Need
      String[] name = test.split("\\.");
      String htmlFile = dir + "\\" + name[0] + ".html";
      FileWriter output = new FileWriter(htmlFile);
      BufferedWriter writer = new BufferedWriter(output);
      writer.write("<html>");
      writer.write("<head>");
      writer.write("</head>");
      writer.write("<body>");
      writer.write("<pre>");
      writer.write(cu.getSource());
      writer.write("</pre>");
      writer.write("</body>");
      writer.write("</html>");
      writer.flush();
    } catch (JavaModelException e) {
    } catch (IOException e) {
      e.printStackTrace();
    }

  }
} 

If you start this plug-in you should be able to create HTML output from a Java source file.

4.3. Restrict the extension - Visible When

Currently our context menu is always displayed. We would like to show it only if a source file is selected. For this we will use a "visible-when" definition.

Add the org.eclipse.core.expressions plug-in as dependency to your plug-in. Select your menu contribution. Using the right mouse add the condition to the command that it should only be visible if a file is selected which represents a ICompilationUnit from the org.eclipse.jdt.core package.

For this exercise you use the predefined variable activeMenuSelection which contains the selection in the menu and iterate over it. If the selection can get adapted toICompilationUnit then the contribution will be visible.

This will result in the following plugin.xml.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            locationURI="popup:org.eclipse.jdt.ui.PackageExplorer">
         <command
               commandId="de.vogella.plugin.htmlconverter.convert"
               label="Create HTML"
               style="push">
            <visibleWhen
                  checkEnabled="false">
               <with
                     variable="activeMenuSelection">
                  <iterate
                        ifEmpty="false"
                        operator="or">
                     <adapt
                           type="org.eclipse.jdt.core.ICompilationUnit">
                     </adapt>
                  </iterate>
               </with>
            </visibleWhen>
         </command>
      </menuContribution>
   </extension>
   <extension
         point="org.eclipse.ui.commands">
      <command
            defaultHandler="de.vogella.plugin.htmlconverter.handler.Convert"
            id="de.vogella.plugin.htmlconverter.convert"
            name="Convert">
      </command>
   </extension>

</plugin> 

If you now start your plug-in, the menu entry should only be visible if at least one compilation unit has been selected.

5. Resources and Marker

Eclipse represents Resources like Projects, Files, Folders, Packages as IResource.

Marker represent additional informations for resources, e.g. an error marker. Every marker can have attributes (key / value combination). Markers can be displayed in the standard view, e.g. the Task, Bookmark or the problems view. To be displayed in these views you have to use predefined attributes.

The following will demonstrate how to create marker for a selected resource.

6. Tutorial: Create Markers for resources

Create a plug-in project "de.vogella.plugin.markers". Add the dependency to org.eclipse.core.resources", "org.eclipse.jdt.core" and "org.eclipse.jdt.ui". Create the command "de.vogella.plugin.markers.AddMarker" with the default handlerAddMarkerHandler in the de.vogella.plugin.markers.handler class and add this command to the menu.

Create the following code.

package de.vogella.plugin.markers.handler;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;

public class AddMarker extends AbstractHandler {

  @Override
  public Object execute(ExecutionEvent event) throws ExecutionException {
    IStructuredSelection selection = (IStructuredSelection) HandlerUtil
        .getActiveSite(event).getSelectionProvider().getSelection();
    if (selection == null) {
      return null;
    }
    Object firstElement = selection.getFirstElement();
    if (firstElement instanceof IJavaProject) {
      IJavaProject type = (IJavaProject) firstElement;
      writeMarkers(type);

    }
    return null;
  }

  private void writeMarkers(IJavaProject type) {
    try {
      IResource resource = type.getUnderlyingResource();
      IMarker marker = resource.createMarker(IMarker.TASK);
      marker.setAttribute(IMarker.MESSAGE, "This a a task");
      marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
} 

If you run you can create a marker in the TODO list if you select a Java project and click your menu entry.

7. Adapters

7.1. Overview

Adapters help to display information about objects in view without having to adjust the existing views. In this example we will create a small view which allows to select objects and use the properties view to display them.

Adapters are used on several places for example you can use an adapter to display your data in the outline view. SeeOutline View Example for an example how to do this.

7.2. Example

We will simple use an adapter to show our data in the property view. Create a new plug-in project "de.vogella.plugin.adapter". Use the "Plug-in with a view" template with the following settings.

Add the dependency "org.eclipse.ui.views" in tab dependencies of plugin.xml.

Create the following data model.

package de.vogella.plugin.adapter.model;

public class Todo {
  private String summary;
  private String description;
  public String getSummary() {
    return summary;
  }
  public void setSummary(String summary) {
    this.summary = summary;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }

} 

Change the code of SampleView.java to the following. After this change you should be able to run your project, open your view and see your todo items.

package de.vogella.plugin.adapter.views;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import de.vogella.plugin.adapter.model.Todo;

public class SampleView extends ViewPart {
  public static final String ID = "de.vogella.plugin.adapter.views.SampleView";

  private TableViewer viewer;

  class ViewLabelProvider extends LabelProvider implements
      ITableLabelProvider {
    public String getColumnText(Object obj, int index) {
      Todo todo = (Todo) obj;
      return todo.getSummary();
    }

    public Image getColumnImage(Object obj, int index) {
      return getImage(obj);
    }

    public Image getImage(Object obj) {
      return PlatformUI.getWorkbench().getSharedImages()
          .getImage(ISharedImages.IMG_OBJ_ELEMENT);
    }
  }

  
   
   
/** * This is a callback that will allow us to create the viewer and initialize * it. */
public void createPartControl(Composite parent) { viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); viewer.setContentProvider(new ArrayContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); getSite().setSelectionProvider(viewer); viewer.setInput(getElements()); }
/** * Passing the focus request to the viewer's control. */
public void setFocus() { viewer.getControl().setFocus(); } // Build up a simple data model private Todo[] getElements() { Todo[] todos = new Todo[2]; Todo todo = new Todo(); todo.setSummary("First Todo"); todo.setDescription("A very good description"); todos[0] = todo; todo = new Todo(); todo.setSummary("Second Todo"); todo.setDescription("Second super description"); todos[1] = todo; return todos; } }

To displays its values in the property view, add the extension point "org.eclipse.core.runtime.adapters" to your project. The data of the extension point should be like the following.

<extension
         point="org.eclipse.core.runtime.adapters">
      <factory
            adaptableType="de.vogella.plugin.adapter.model.Todo"
            class="de.vogella.plugin.adapter.TodoAdapterFactory">
         <adapter
               type="org.eclipse.ui.views.properties.IPropertySource">
         </adapter>
      </factory>
</extension> 

Implement the factory and the new class "TodoPropertySource" which implements "IPropertySource".

package de.vogella.plugin.adapter;

import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.ui.views.properties.IPropertySource;

import de.vogella.plugin.adapter.model.Todo;

public class TodoAdapterFactory implements IAdapterFactory {

  @Override
  public Object getAdapter(Object adaptableObject, Class adapterType) {
    if (adapterType== IPropertySource.class && adaptableObject instanceof Todo){
      return new TodoPropertySource((Todo) adaptableObject);
    }
    return null;
  }

  @Override
  public Class[] getAdapterList() {
    return new Class[] { IPropertySource.class };
  }

} 

package de.vogella.plugin.adapter;

import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

import de.vogella.plugin.adapter.model.Todo;

public class TodoPropertySource implements IPropertySource {

  private final Todo todo;

  public TodoPropertySource(Todo todo) {
    this.todo = todo;
  }


  @Override
  public boolean isPropertySet(Object id) {
    return false;
  }

  @Override
  public Object getEditableValue() {
    return this;
  }

  @Override
  public IPropertyDescriptor[] getPropertyDescriptors() {

    return new IPropertyDescriptor[] {
        new TextPropertyDescriptor("summary", "Summary"),
        new TextPropertyDescriptor("description", "Description") };
  }

  @Override
  public Object getPropertyValue(Object id) {
    if (id.equals("summary")) {
      return todo.getSummary();
    }
    if (id.equals("description")) {
      return todo.getDescription();
    }
    return null;
  }

  @Override
  public void resetPropertyValue(Object id) {

  }

  @Override
  public void setPropertyValue(Object id, Object value) {
    String s = (String) value;
    if (id.equals("summary")) {
      todo.setSummary(s);
    }
    if (id.equals("description")) {
      todo.setDescription(s);
    }
  }

} 

If you run your workbench and open your View via Windows -> Show View -> Others -> Sample Category -> Sample View and the property view you should be able to view your data.

8. Eclipse Resources

You can register IResourceChangeListener on resources in Eclipse. For example if you have a project you can add or remove a resource listener to or from it.

// Add listener
project.getWorkspace().addResourceChangeListener(listener);

// Remove listener
project.getWorkspace().removeResourceChangeListener(listener);

// Example resource listener
private IResourceChangeListener listener = new IResourceChangeListener() {
    public void resourceChanged(IResourceChangeEvent event) {

    if (event.getType() == IResourceChangeEvent.PRE_CLOSE || event.getType() == IResourceChangeEvent.PRE_DELETE) {
        if (event.getResource().equals(project)) {
          // Project deleted or closed
          // Do something
        }
        return;
      }

      if (resource == null)
        return;

      IResourceDelta delta = event.getDelta().findMember(new Path(resource.getURI().toPlatformString(false)));
      if (delta == null) {
        return;
      }

      if (delta.getKind() == IResourceDelta.REMOVED) {
        // Resource delete
        // Do something
      }
    }

  }; 

9. Installing your plug-in

9.1. Overview

You have several options to make your plug-in available in your Eclipse IDE.

To use your plug-ins in your standard Eclipse installation you can directly install, export into and and place it into your Eclipse installation or you can create an update site and use the Eclipse update manager to install the plug-in.

The following describes all approaches.

9.2. Installing your plug-in directly

If you export your plug-in locally you can put it into the Eclipse dropin folder of your Eclipse installation. After a restart of your Eclipse your plug-in should be available and ready to be used.

If you want to install your plug-in into your running Eclipse IDE, you can also directly install the plug-in into your running Eclipse IDE.

In the export wizard dialog select in this case Install into host. Repository.

If you create and export an feature you can use the Eclipse update manager directly if you point in the update manager to the createdmetadata repository.

9.3. Export plug-in and put into dropin folder

The following describes how you can export your plug-in and place it into a specific folder to install it into Eclipse.

Select your plugin.xml and select the tab overview. Press the Export Wizard hyperlink.

Select the plug-in you want to export.

This will create a jar in the selected directory. Copy this jar to the dropin directory in your Eclipse installation directory and re-start Eclipse.

After a restart of Eclipse your plug-in should now be available in your Eclipse installation and ready to be used. For example if you contributed a newPart you find it under the WindowsShow View menu entry.

9.4. Create a p2 update site

You can also create an update site for your plug-in (via a feature project) and use the Eclipse update manager to install the feature (with the plug-in). To create an update site you require a feature project.

You also need a category as the Eclipse p2 update manager shows by default only features with a category. While the user can de-select this grouping it is often easier to deploy the feature including an category.

Create a feature project for your plug-in and add your plug-in to this feature.

In your feature project create via the menu entry FileNewOtherPlug-in development Category Definition a new category definition.

Press the New Category button and create a category with a name which describes your functionality. Add your feature to this category.

Export your feature via File ExportDeployable features . Deploy it to a local directory on your machine. Make sure you select on the Option tab yourcategory.xml file. Also ensure to select the Generate metadata repository option on the export dialog.

Use the Eclipse Update manager to install this new feature into your Eclipse IDE. Use the update manager and point to your local directory. Restart the IDE after installation.

After a restart of Eclipse your plug-in should now be available in your Eclipse installation and ready to be used. For example if you contributed a new view you find it under theWindowsShow View men entry.

10. Exercise: Install your plug-in

Install your plug-in into your Eclipse IDE via your preferred choice.

11. Tools

11.1. Eclipse Yari

It's a comprehensive tool suite to debug, spy, spider, inspect and navigate Eclipse based application GUIs (Workbench or RCP).http://sourceforge.net/projects/yari/

11.2. VisualVM

VisualVM is a debugging tool which can be integrated into Eclipse. http://visualvm.java.net/eclipse-launcher.html

11.3. JVM Monitor

JVM Monitor is a Java profiler integrated with Eclipse to monitor CPU, threads and memory usage of Java applications.http://www.jvmmonitor.org/index.html

12. Thank you

Please help me to support this article:

Flattr this

13. Questions and Discussion

Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use thewww.vogella.com Google Group. I have created a short listhow to create good questions which might also help you.

14. Links and Literature

14.1. Source Code

Source Code of Examples

14.3. vogella Resources

vogella TrainingAndroid and Eclipse Training from the vogella team

Android TutorialIntroduction to Android Programming

GWT TutorialProgram in Java and compile to JavaScript and HTML

Eclipse RCP TutorialCreate native applications in Java

JUnit TutorialTest your application

Git TutorialPut everything you have under distributed version control system

Book Description Publication Date: December 21, 2008 | ISBN-10: 0321553462 | ISBN-13: 978-0321553461 | Edition: 3 Producing a commercial-quality plug-in means going above and beyond the minimal requirements needed to integrate with Eclipse. It means attending to all those details that contribute to the “fit and polish” of a commercial offering. This comprehensive guide covers the entire process of plug-in development, including all the extra steps needed to achieve the highest quality results. Building on two internationally best-selling previous editions, Eclipse Plug-ins, Third Edition, has been fully revised to reflect the powerful new capabilities of Eclipse 3.4. Leading Eclipse experts Eric Clayberg and Dan Rubel present detailed, practical coverage of every aspect of plug-in development, as well as specific, proven solutions for the challenges developers are most likely to encounter. All code examples, relevant API listings, diagrams, and screen captures have been thoroughly updated to reflect both the Eclipse 3.4 API and the latest Java syntax. In addition, Clayberg and Rubel have completely revamped their popular Favorites View case study, reworking much of its content and recreating its code from scratch. The authors carefully cover new functionality added to existing Eclipse features, such as views and editors, and fully explain brand-new features such as Commands, GEF, and PDE Build. This extensively revised edition Thoroughly covers Eclipse’s new preferences Illuminates the powerful new Eclipse Command Framework, which replaces Eclipse’s older Action Framework Presents extensive new discussions of using commands with views and editors Introduces Mylyn, the new task-focused interface that reduces information overload and simplifies multi-tasking Contains an all-new chapter on using the Graphical Editing Framework (GEF) to build dynamic, interactive graphical user interface elements Walks you step by step through the entire PDE Build process Shows how to create update sites with p2, which replaces Eclipse’s old Update Manager This book is designed for every experienced developer interested in extending the Eclipse platform, the Rational Software Development Platform, or any other platform that supports Eclipse plug-ins.
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值