开发Eclipse插件的最佳实践

日期: 2011-11-15 作者:Andy FlattMickael Maison 来源:TechTarget中国 英文

  在为IDE Eclipse环境开发插件时,您要考虑到几个设计要素,这些要素确保您:

  • 不用锁定用户界面线程。
  • 在不影响性能的情况下修饰用户界面。
  • 在后台处理数据。

  本教程将讨论如何使用这些设计要素来处理和显示那些与存储在工作区中的资源相关的数据。我们将检查Eclipse如何提供一个标记界面来存储和处理与资源相关的信息。

  我们将提供处理资源数据标记的最佳实践。首先,我们展示如何标记数据,然后构建知识来在用户界面上表示标记,最后在资源变更时更新标记。在本文中,资源为Eclipse对象,可实现IResource界面,比如项目、文件、文件夹以及Java对象(其中包括包、类以及源)。

  本教程是针对那些可以编写基本插件并且又想学习处理 Eclipse 资源的最佳实践的开发人员。

  Eclipse.org记录了许多独特的扩展点和界面。本文将帮助您选择结合使用这些扩展点和界面的最佳实践。 进一步学习如何利用现有的Eclipse函数来提供新的功能。

  第 1 部分:创建您自己的标记

  标记是什么?

  标记用于在不更改资源的情况下将信息链接到资源上。被标记信息的常见示例有断点、书签和编译错误。以编译错误为例,每一次执行编译作业,作业会通过创建一个新的标记来浏览源并突出错误。

  扩展标记

  在本教程的第一部分,我们将创建我们自己的标记。只要通过标记扩展点,并且只要编写一行代码即可完成此项工作。

  您可以通过扩展IMarker扩展点org.eclipse.core.resources.markers来创建您自己的标记。首先,在plugin.xml文件中添加 清单1中的代码。也就是说,您将以id为com.ibm.mymarkers.mymarker创建一个名为My Marker的标记。它的超类型为org.eclipse.core.resources.marker。这是最基本的标记类型。您可以扩展其他提供稍微更具体的功能的超类型。其他的超类型有:

  • org.eclipse.core.resources.problemmarker
  • org.eclipse.core.resources.textmarker

  注意:您可以随需使用任意多的这些超类型。

  清单 1. 清单1来自plugin.xml的标记扩展定义
     

以下是引用片段:
<extension point=”org.eclipse.core.resources.markers” id=”com.ibm.mymarkers.mymarker”
  name=”My Marker”>
 <super type=”org.eclipse.core.resources.marker”/>
 <persistent value=”false”/>
     <attribute name=”description”/>
</extension>

  注意清单1中的两个要素persistent和attribute。这些都是分配给mymarker标记的属性。Persistent指明标记是否应该存储在工作区中。还有另外一个分配给mymarker的新属性description。

  使用新标记

  您可以通过调用所需资源上的createMarker方法来创建一个标记。同时,您也可以为其设置属性。

  清单 2 中所示的方法也可以用来创建标记。只需输入IResource,将其链接到标记。创建后,您就可以设置其属性。

  清单 2. 清单2创建新标记类型的Java代码
     

以下是引用片段:
public static IMarker createMarker(IResource res)
throws CoreException {
       IMarker marker = null;
       //note: you use the id that is defined in your plugin.xml
       marker = res.createMarker(“com.ibm.mymarkers.mymarker”);
       marker.setAttribute(“description,” “this is one of my markers”);
       //note: you can also use attributes from your supertype
       marker.setAttribute(IMarker.MESSAGE, “My Marker”);
       return marker;

  查找您的标记

  要查找与IResource相关的标记,您可以查询资源来获取所有具有指定id的标记,并指定是否搜索相关资源。要搜索标记,调用资源上的findMarkers方法。指定诸如标记类型和搜索深度的参数。

  清单3中的代码使用IResource.DEPTH_ZERO参数查找直接与该资源链接的标记。

  清单3. 查找新标记类型的Java代码
     

以下是引用片段:
public static final String MARKER = “com.ibm.mymarkers.mymarker”;
public static List<IMarker> findMarkers(IResource resource) {
        try {
               return Arrays.asList(resource.findMarkers(MARKER, true, 
 IResource.DEPTH_ZERO));
        } catch (CoreException e) {
               return new ArrayList<IMarker>();
        }
    }

  将资源深度更改为IResource.DEPTH_INFINITE会返回与其相关的标记或任何子资源。例如,您可以传入包,并获取与包中资源相链接的所有标记。

  第 2 部分:使用注释来显示和更新标记

  注释是什么?

  注释用于标记编辑器内的一个文本区域。它们广泛用于在Eclipse中显示信息,比如错误、警告、构建问题、任务或断点。注释在编辑器标尺上和文本上都可看到。图1列出显示语法错误的注释。

图 1. 图1注释的示例

图 1. 图1注释的示例

  常见的注释实现是,在解析文件并且挑选出诸如错误和“todo”标签时生成标记。这通常在构建时完成。将其他的链接到持久标记,如断点。该示例所使用的是持久标记。

  用户查看注释的方法可以使用菜单 General > Editors > Text Editors > Annotations 下的首选项面板进行定制。也就是说用户自定义注释不需要执行额外的工作。

图 2. 图2注释首选项面板的屏幕截图

图 2. 图2注释首选项面板的屏幕截图

  标记扩展点的属性

  在本教程的第1部分中,标记只扩展了默认的标记类型。在第2部分,我们将扩展文本标记类型,以标记文本位置。此类型定义了两个关键属性:charStart和charEnd。我们也希望标记在会话间能持久,所以我们将 persistent 值改为 true。为此,我们需要更新清单4中所定义的标记。

  清单 4. 清单 4 来自 plugin.xml 的标记扩展定义
     

以下是引用片段:
<extension point=”org.eclipse.core.resources.markers” id=”com.ibm.mymarkers.mymarker”
  name=”My Marker”>
 <super type=”org.eclipse.core.resources.textmarker”/>
 <super type=”org.eclipse.core.resources.marker”/>
 <persistent value=”true”/>
</extension>

  定义您的注释规范扩展

  要创建您自己的注释,使用扩展点org.eclipse.ui.editors.markerAnnotationSpecification(参见清单5)。它定义了注释的属性以及其默认显示选项。

  清单 5. 清单5来自plugin.xml的注释扩展定义
     

以下是引用片段:
<extension point=”org.eclipse.ui.editors.markerAnnotationSpecification”
  id=”myannotationspecification” name=”MyAnnotation”>
 <specification annotationType=”com.ibm.example.myannotation”
   label=”MyAnnotation”
   icon=”icons/sample.gif”
   overviewRulerPreferenceKey=”clruler”
   overviewRulerPreferenceValue=”true”
   colorPreferenceKey=”clcolor”
   colorPreferenceValue=”255,255,0″
   textPreferenceKey=”cltext”
   textPreferenceValue=”true”
   verticalRulerPreferenceKey=”clvertical”
   verticalRulerPreferenceValue=”true”
   textStylePreferenceKey=”clstyle”
   textStylePreferenceValue=”BOX”>
 </specification>
</extension>

  XML中我们将用来链接到规范的部分是id和annotationType属性。Eclipse.org记录了用于自定义的其他属性。

  下一步是使用扩展点org.eclipse.ui.editors.annotationTypes把现有的标记链接到新的注释规范中。我们使用来自规范的注释类型和来自标记定义的id来链接规范。

  清单6. 清单6来自plugin.xml的注释类型定义
     

以下是引用片段:
<extension point=”org.eclipse.ui.editors.annotationTypes”>
                <type markerSeverity=”0″
                                        super=”org.eclipse.ui.workbench.texteditor.info”
                                        name=”com.ibm.example.myannotation”
     markerType=”com.ibm.mymarkers.mymarker”/>
</extension>

  创建并添加一个注释到编辑器

  清单7中的代码用于创建并添加注释到编辑器。

  清单 7. 清单7向编辑器添加一个新的注释

以下是引用片段:
public static void addAnnotation(IMarker marker, ITextSelection selection, 
       ITextEditor editor) {
      //The DocumentProvider enables to get the document currently loaded in the editor
      IDocumentProvider idp = editor.getDocumentProvider();
      //This is the document we want to connect to. This is taken from 
      //the current editor input.
      IDocument document = idp.getDocument(editor.getEditorInput());
      //The IannotationModel enables to add/remove/change annotation to a Document 
      //loaded in an Editor
      IAnnotationModel iamf = idp.getAnnotationModel(editor.getEditorInput());
      //Note: The annotation type id specify that you want to create one of your 
      //annotations
      SimpleMarkerAnnotation ma = new SimpleMarkerAnnotation(
    “com.ibm.example.myannotation”,marker);
      //Finally add the new annotation to the model
      iamf.connect(document);
      iamf.addAnnotation(ma,newPosition(selection.getOffset(),selection.getLength()));
      iamf.disconnect(document);

  保持标记和注释同步

  注释模式负责在文档被编辑时移动注释。然而,在注释移动时,它并不更新标记的属性。在这种情况下,我们要更新标记的charStart和charEnd属性。最后的扩展点为标记更新器(updater)。它定义了一个类,用于在移动注释时更新标记。

  清单 8. 清单8来自plugin.xml的标记更新器定义
     

以下是引用片段:
<extension point=”org.eclipse.ui.editors.markerUpdaters”> 
               <updater
                       id=”com.ibm.example.MarkerUpdater”
                       class=”com.ibm.example.mymarker.MarkerUpdater”
                       markerType=”com.ibm.mymarkers.mymarker”>
               </updater>
</extension>: 

  我们使用IMarkerUpdater界面来提供我们在移动注释时想要执行的代码。清单9中显示的类是我们的标记更新器。我们感兴趣的代码在updateMarker方法中。 此处,我们用它来更新标记的charStart和charEnd属性。

  清单 9. 清单9标记更新器代码
     

以下是引用片段:
public class MarkerUpdater implements IMarkerUpdater {
       /*
       *Returns the attributes for which this updater is responsible.
       *If the result is null, the updater assumes responsibility for any attributes.
       */
       @Override
       public String[] getAttribute() {
            return null;
       }
       @Override
       public String getMarkerType() {
             //returns the marker type that we are interested in updating
            return “com.ibm.mymarkers.mymarker”;
       }
       @Override
       public boolean updateMarker(IMarker marker, IDocument doc, Position position) {
             try {
                 int start = position.getOffset();
                   int end = position.getOffset() + position.getLength();
                   marker.setAttribute(IMarker.CHAR_START, start);
                   marker.setAttribute(IMarker.CHAR_END, end);
                   return true;
             } catch (CoreException e) {
                   return false;
             }
       }

  第3部分:使用修饰符来识别已标记的IResources

  修饰符是什么?

  在Eclipse中,修饰符用于为工作区中的对象添加视觉信息。他们通常显示对象类型以及目前与该对象相关的任何重要属性。图3显示了如何在包资源管理器中将修饰符显示给用户。该修饰符显示了哪些项为Java源文件,或哪些项为包,并且显示了包含警告或错误的源和包的标记图标。这里,修饰符也用来添加细节,比如文件是否与存储库同步。

图 3. 图3用符号图标修饰的包和源

图 3. 图3用符号图标修饰的包和源

  定义您自己的修饰符

  添加我们的修饰符的第一步是扩展org.eclipse.ui.decorators扩展点。它启用新修饰符的定义,并且选择它将要修饰哪种对象。

  此处重要的字段是:

  class,它必须是实现ILightweightLabelDecorator的类的完全限定名(将lightweight设置为true)。 enablement,它包含修饰符所应用的 Eclipse 对象列表。

  清单 10. 清单10来自plugin.xml的修饰符定义
     

以下是引用片段:
<extension point=”org.eclipse.ui.decorators”>  
 <decorator   id=”com.ibm.example.filedecorator”   
   label=”MyMarker Decorator”   
   state=”true”   
   class= “com.ibm.example.mymarker.FileDecorator”   
   adaptable=”true”   
   lightweight=”true”>   
  <enablement>
   <objectClass name=”org.eclipse.core.resources.IResource”/>   
  </enablement>  
 </decorator>
</extension>

  注意:轻量级与非轻量级:根据API, 非轻量级修饰符可能会在新版本的Eclipe中被弃用。

  我们的文件修饰符类

  我们需要实现FileDecorator类来决定修饰符的行为。这一类必须实现ILightweightLabelDecorator。用它来扩展LabelProvider的想法非常好,因为它可以让我们只重写我们感兴趣的方法,即 decorate()。

  decorate()的基本实现如清单11所示。

  清单 11. 清单11decorate()的简单实现
     

以下是引用片段:
public void decorate(Object resource, IDecoration decoration)  {
 decoration.addOverlay(ImageDescriptor.createFromFile(FileDecorator.class, 
     “/icons/sample.gif”), IDecoration.TOP_RIGHT);
 decoration.addPrefix(“My Prefix “);
 decoration.addSuffix(” My Suffix”);
}

  IDecoration对象也可用于自定义字体、文本或背景颜色。

图 4. 图4清单11中用来修饰IResources的代码屏幕截图

图 4. 图4清单11中用来修饰IResources的代码屏幕截图

  decorate()的第一个参数可以用来筛选我们要修饰的资源。如果我们只想要修饰包含指定标记的资源,就使用如 清单12所示的代码。

  清单12. 清单12使用指定标记修饰资源
     

以下是引用片段:
public void decorate(Object resource, IDecoration decoration) {
 if(resource instanceof IResource){
  List<IMarker> markers = MyMarkerFactory.findMarkers((IResource) resource);
  if (markers.size() > 0) {
   decoration.addSuffix(”  Marker !!”);
  }
 }
}

  您已经遵循了本教程的步骤,接下来该做什么?

  进一步的改进包括:

  • 为标记添加可编辑的属性。允许用户更改标记的状态。
  • 自动创建和删除标记。 使用后台处理作业来自动创建、更新和删除标记。
  • 自定义标记的hover。使用高级标记hover来支持HTML或多媒体内容。

  在本教程中,我们使用了Eclipse来轻松创建和自定义标记,并执行高级的资源标记工作。 鼓励开发人员使用这个简单而又强大的工具来把他们的插件完美地整合到Eclipse IDE中。但是,注意,如果此特性用得太广泛,则对用户来说会显得很突兀。此外,将Eclipse用户界面指南考虑在内来维护Eclipse的外观与风格是开发人员的职责,参见 参考资料。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 既熟悉又陌生的开源项目

    Eclipse基金会已成立整整10年了。目前这个开源组织拥有众多项目,其中就包含了最为出名的Java IDE Eclipse以及Mylyn。本文,我们将给您介绍10个已经“掀起波澜”的Eclipse项目。

  • Eclipse中隐藏的5个非常有用的功能

    Eclipse就是一头野兽,它也是一套设备,神秘但更具威力。有些人称它为一个持续变形机。另一些人则称它是一个变异体。

  • 推荐五个提高Java开发效率的工具

    Java已经越来越受程序的重视,俗话说磨刀不误砍柴工,好的工具可以提高Java开发效率,这些工具你都了解吗?

  • Java程序员应该知道的十个调试技巧

    任何一种编程语言都离来开调试这一环节,调试可以帮助识别和解决应用程序缺陷,那么做为java程序呗,你知道在Eclipse中怎样进行调试吗?