自己动手编写Eclipse扩展点

原创 2004年09月15日 20:27:00

  扩展(Extension)是Eclipse中一个关键的机制,plug-in利用扩展向Eclipse平台添加新功能。但是扩展不能随意地创建,必须按照扩展点(extension point)定义的规范进行明确的声明,Eclipse才能认出这些扩展。我们不仅可以使用Eclipse提供的众多现成的扩展点,而且还可以定义新的扩展点,并在该扩展点上进行扩展。
  当然,扩展点的定义比较复杂。不过Eclipse为用户提供了图形化的编辑界面,我们只要输入一些信息,Eclipse就会自动生成代码,使扩展点的定义变得非常简单。
  下面我们就来看看如何在Eclipse中创建一个新的扩展点,并在这个扩展点上进行扩展。
  我们需要做以下的工作:
1.设计该扩展点
2.定义扩展点,即编写扩展点的清单文件
3.编写代码来载入该扩展点的扩展
  我们以创建workList扩展点为例,进行详细介绍。
  worklist完成的功能是:创建一个view,在其中以树状显示系统中可用的功能模块,通过双击某个模块节点,执行该扩展定义的方法(method)。其实相当于一个控制台,通过控制台来运行不同的功能。
  由于Eclipse是由一个运行时核心(runtime core)和众多插件组成的,我们也将workList扩展点定义在一个插件中,有关workList的代码文件也放在这个插件中,这样便于查找和修改,也不影响Eclipse本身的代码。
 
1. 定义扩展点
  首先我们要创建一个存放新扩展点信息的插件net.softapp.worklist,这个插件对org.eclipse.ui.views进行扩展,以下是插件的plugin.xml文件在views扩展点的信息:
  <extension        
   point="org.eclipse.ui.views">
         <category
                     name="WorkListCategory"
                     id="WorkListCategory"/>
                           <view
                                       icon="icons/sample.gif"
                                       class="net.softapp.internal.worklist.WorkListView"
                                       category="WorkListCategory"
                                       name="WorkList视图"
                                       id="net.softapp.internal.worklist.WorkListView"/>
  </extension>
  这样就可以通过“window->show view->other”,在弹出的“Show view”对话框中选择“WorkList视图”,打开视图,我们用这个视图显示workList扩展点的所有扩展信息。“Show View”对话框显示了Eclipse中定义所有视图,即所有org.eclipse.views扩展点的扩展。了解这一点很重要,因为我们在编写workList扩展点代码时,就可以模仿甚至拷贝views扩展点的代码。
  下面,我们要在net.softapp.worklist插件中定义workList扩展点。
  扩展点的定义文件按照Eclipse的存放方式,一般存放在schema目录下,我们把文件命名为worklist.exsd。内容如下,此内容由PDE生成:
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="mtn.esip.worklist">
<annotation>
      <appInfo>
         <meta.schema plugin="net.softapp.worklist" id="workList" name="workList"/>
         <!--通过这个定义,我们可以看出,定义的扩展点的id是 net.softapp.worklist.workList,以后引用时要注意,同时注意大小写-->
      </appInfo>
      <documentation>
         [Enter description of this extension point.]
      </documentation>
   </annotation>

   <element name="extension">
      <complexType>
         <choice minOccurs="0" maxOccurs="unbounded">
            <element ref="category" minOccurs="0" maxOccurs="1"/>
            <element ref="worklist" minOccurs="0" maxOccurs="1"/>
         </choice>
         <attribute name="point" type="string" use="required"><!--定义point-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="id" type="string"><!--定义id-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="name" type="string"><!--定义name-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
      </complexType>
   </element>
 
  <!--定义category-->
   <element name="category">
      <complexType>
         <attribute name="name" type="string"><!--定义category/name-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="id" type="string"><!--定义category/id。引用category时,必须指出应用的id,而name给出了一个可供显示的直观的名字-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="parentCategory" type="string"><!--定义父category,也就是说我们的category可以嵌套形成树状结构-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
      </complexType>
   </element>

   <!--定义worklist,注意大小写-->
   <element name="worklist">
      <complexType>
         <attribute name="name" type="string"><!--定义worklist/name,可供显示的直观的名字-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="icon" type="string"><!--定义worklist/icon,可供显示的直观的图标-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="category" type="string">!--定义worklist/category,存放的category位置。如果引用嵌套形式的category,则采用 parent_id/child_id的形式 -->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
         <attribute name="class" type="string"><!--定义worklist/class,实现功能的类名称-->
            <annotation>
               <documentation>                 
               </documentation>
               <appInfo>
                  <meta.attribute kind="java"/>
               </appInfo>
            </annotation>
         </attribute>
         <attribute name="id" type="string" use="required"><!--定义worklist/id,唯一标志-->
            <annotation>
               <documentation>                 
               </documentation>
            </annotation>
         </attribute>
      </complexType>
   </element>
   <!--以下内容为PDE自动生成,与我们的编程无关-->
   <annotation>
      <appInfo>
         <meta.section type="since"/>
      </appInfo>
      <documentation>
         [Enter the first release in which this extension point appears.]
      </documentation>
   </annotation>

   <annotation>
      <appInfo>
         <meta.section type="examples"/>
      </appInfo>
      <documentation>
         [Enter extension point usage example here.]
      </documentation>
   </annotation>

   <annotation>
      <appInfo>
         <meta.section type="apiInfo"/>
      </appInfo>
      <documentation>
         [Enter API information here.]
      </documentation>
   </annotation>

   <annotation>
      <appInfo>
         <meta.section type="implementation"/>
      </appInfo>
      <documentation>
         [Enter information about supplied implementation of this extension point.]
      </documentation>
   </annotation>

   <annotation>
      <appInfo>
         <meta.section type="copyright"/>
      </appInfo>
      <documentation>        
      </documentation>
   </annotation>

</schema>
  这样我们就定义好了扩展的属性。
  然后在plugin.xml加入:
     <extension-point id="workList" name="workList" schema="schema/workList.exsd"/>
  就定义好了!
 
2. 实现扩展
  定义完扩展之后,接下来要编写解析此扩展的相关代码。可喜的是,Eclipse为我们提供了大量的API可以调用,省下了若干代码的编写。另外我们还可以借鉴Eclipse实现的其他代码,通过模仿来编写我们自己的解析代码。本例参考了View的解析部分。同View,我们定义了WorkListDescriptor,WorkListRegistry,WorkListRegistryReader.其中WorkListDescriptor完成对上述定义的解析,WorkListRegistry存放了其他插件对workList扩展的相关信息,WorkListRegistryReader则从WorkListRegistry读取信息供我们使用。
  此处代码从略,具体请参考View实现部分的ViewDescriptor,ViewRegistry,ViewRegistryReader相关代码。
 
3. 编写界面部分
  根据1对View的扩展,我们需要编写界面部分。此处请参考View插件的编写。我们在此对WorkListPlugin添加了一个方法用以从注册表中读取扩展信息:
   public IWorkListRegistry getWorkListRegistry() {
  if (workListRegistry == null) {
   workListRegistry = new WorkListRegistry();
   try {
    WorkListRegistryReader reader = new WorkListRegistryReader();
    reader.readWorkList(Platform.getExtensionRegistry(), workListRegistry);
   } catch (CoreException e) {
    // cannot safely show a dialog so log it
    WorkbenchPlugin.log("Unable to read workList registry.", e.getStatus()); //$NON-NLS-1$
   }
  }
  return workListRegistry;
 }
其中WorkListRegistryReader.readWorkList定义如下:
/**
 * Read the workList extensions within a registry.
 */
public void readWorkList(IExtensionRegistry in, WorkListRegistry out)
 throws CoreException {
 // this does not seem to really ever be throwing an the exception
 workListRegistry = out;
 readRegistry(in, WorkListPlugin.getDefault().getPluginId(), "workList");
 out.mapWorkListToCategories();
}
可见,我们不需要编写复杂的代码就可以读取注册表中存放的扩展信息!
  我们对workList扩展的显示是采用了TreeView,代码如下(WorkListView):
   protected TreeViewer createViewer(Composite parent) {
  TreeViewer viewer =
   new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
   viewer.setUseHashlookup(true);
   viewer.setContentProvider(new WorkListContentProvider());
   viewer.setLabelProvider(new WorkListLabelProvider());
   workListReg = WorkListPlugin.getDefault().getWorkListRegistry(); 
   viewer.setInput(workListReg);
   initListeners(viewer);
   return viewer;
 }
这样,就可以实现显示了。
  那么,怎样实现选择某个扩展后,通过双击执行其功能呢?我们对TreeViewer添加了鼠标双击事件支持,关键代码如下:
    protected void handleDoubleClick(DoubleClickEvent event) {
   IStructuredSelection selection = (IStructuredSelection) event.getSelection();
   Object element = selection.getFirstElement();

   TreeViewer viewer = getWorkListViewer();
   if (viewer.isExpandable(element)) {
    viewer.setExpandedState(element, !viewer.getExpandedState(element));   
   }else {
    WorkListDescriptor workList = (WorkListDescriptor)element;
    try {
      IWorkListPart workListPart = (IWorkListPart) workList.createWorkList();
      workListPart.run();
    } catch (CoreException e) {
     // should add something to handle the exception
    }
   }

  }
其中IWorkListPart很简单,使所有实现workList扩展必须实现的接口:
public interface IWorkListPart {
 
 public void run();

}
只有一个run方法(可以自行添加其他的支持)。
  其中WorkListDescriptor.createWorkList方法实现根据class的字符串创建一个对象,也是超级简单,因为Eclipse已经为我们编好了:
   public Object createWorkList() throws CoreException {
  Object obj = WorkbenchPlugin.createExtension(configElement, "class");
  return  obj;
 }
  这样就可以执行扩展的功能了。
  但是别忘了,还要编写pluin.xml,否则Eclipse可不认吆:
     <extension
         point="net.softapp.worklist.workList">
      <category
            name="HelloTest"
            id="HelloTest"/>
      <worklist
            icon="icons/example.ico"
            class="net.softapp.internal.worklist.Hello"
            category="HelloTest"
            name="Hello"
            id="net.softapp.internal.worklist.Hello"/>
   </extension>
  
4.测试新扩展点
  
   OK,开始运行Eclipse的plugin调试环境,打开WorkList视图,看看在树状列表里是不是有一个HelloTest目录,下面有Hello。双击它,你编写的代码出来了吧!

教你怎样扩展Eclipse的扩展点(一)

  现在手头上做的基于Eclipse RCP的上海佳吉快运第三代运营系统的项目也快接近尾声了,经历一个项目从设计开发到马上完成的过程,也从中向同事们学到了很多的东西,所以今天我想将项目中用到的一些技术...
  • vwpolo
  • vwpolo
  • 2008年02月13日 18:13
  • 2722

eclipse自定义扩展点

一、组成 一个扩展点(Extension Point)包括ID、Name及Schema文件,shema文件以ID命名,后缀为.exsd,存放在插件schema目录下。   使用eclipse的向导...
  • Yangyan518
  • Yangyan518
  • 2016年01月26日 16:46
  • 1105

eclipse plugin 菜单

简介: 菜单是各种软件及开发平台会提供的必备功能,Eclipse 也不例外,提供了丰富的菜单,包括主菜单(Main Menu),视图 / 编辑器菜单(ViewPart/Editor Menu)和上下文...
  • hanghangaidoudou
  • hanghangaidoudou
  • 2015年09月02日 09:45
  • 1040

eclipse的seach功能介绍

引言 查找功能是计算机语言开发环境 / 平台的一个非常重要的特性。Eclipse 也不例外,它提供了丰富的查找功能(用户可以输入正则表达式或任意字符串,指定查找范围和匹配选项等等),并且提供了简单易...
  • beijing20120926
  • beijing20120926
  • 2013年11月25日 15:42
  • 1225

Eclipse plugins 插件开发学习 - 扩展点介绍

Eclipse 存在很多的扩展点:1. org.eclipse.ui.actionSets                  给 Eclipse 增加主菜单和工具栏 (Workbench Window...
  • subchen
  • subchen
  • 2007年11月01日 12:18
  • 3484

教你怎样扩展Eclipse的扩展点(三)

接下来,我们开始实现 扩展点的一些 功能吧,新增选中的包和类: 为了方便起见,我将这些类的源代码贴出来  TheFirstAction .java:  package org.vwpolo.rcp....
  • vwpolo
  • vwpolo
  • 2008年02月13日 18:18
  • 2014

使用Eclipse中的更新配置界面

在Eclipse中的众多特性中有一条可以自动更新的功能,  我们可能在实际使用中也需要Eclipse那样的更新功能,而Eclipse提供了更新和管理插件的配置对话框,在这里我们可用发扬发扬"拿来主义"...
  • vwpolo
  • vwpolo
  • 2008年03月04日 17:18
  • 3476

开发Eclipse插件(Plug-ins)

Eclipse最有魅力的地方就是它的插件体系结构。在这个体系中重要的概念是扩展点(extension points),也就是为插件提供的接口。每一个插件都是在现有的扩展点上开发,并可能还留有自己的扩展...
  • romans1981
  • romans1981
  • 2005年02月28日 09:05
  • 1589

教你怎样扩展Eclipse的扩展点(四)

现在差不多了,我们在 ApplicationActionBarAdvisor .java 文件的 fillMenuBar  方法调用  ExtensionHelper 的方法就行了      prot...
  • vwpolo
  • vwpolo
  • 2008年02月13日 18:19
  • 1301

Eclipse 引用扩展点、收集扩展点

在自定义扩展点时 有个reference属性,称之为引用 收集扩展点:获取自定义扩展点信息时,称之为收集。 以下是代码示例,根据需要自行更改。 public void createPartC...
  • soszou
  • soszou
  • 2012年10月15日 23:11
  • 1559
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自己动手编写Eclipse扩展点
举报原因:
原因补充:

(最多只允许输入30个字)