[zt]自己动手编写Eclipse扩展点

本文介绍如何在Eclipse中创建扩展点并实现扩展。包括定义扩展点、实现扩展、编写界面及测试流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FROM:http://wjj-tt.spaces.live.com/blog/

扩展(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扩展点的信息:
  

xml 代码
  1. <extension               
  2.    point="org.eclipse.ui.views">      
  3.          <category      
  4.                      name="WorkListCategory"     
  5.                      id="WorkListCategory"/>      
  6.                            <view      
  7.                                        icon="icons/sample.gif"     
  8.                                        class="net.softapp.internal.worklist.WorkListView"     
  9.                                        category="WorkListCategory"     
  10.                                        name="WorkList视图"     
  11.                                        id="net.softapp.internal.worklist.WorkListView"/>      
  12.   </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 代码
  1. <?xml version='1.0' encoding='UTF-8'?>      
  2. <!-- Schema file written by PDE -->      
  3. <schema targetNamespace="mtn.esip.worklist">      
  4. <annotation>      
  5.       <appInfo>      
  6.          <meta.schema plugin="net.softapp.worklist" id="workList" name="workList"/>      
  7.          <!--通过这个定义,我们可以看出,定义的扩展点的id是 net.softapp.worklist.workList,以后引用时要注意,同时注意大小写-->      
  8.       </appInfo>      
  9.       <documentation>      
  10.          [Enter description of this extension point.]      
  11.       </documentation>      
  12.    </annotation>       
  13.      
  14.    <element name="extension">      
  15.       <complexType>      
  16.          <choice minOccurs="0" maxOccurs="unbounded">      
  17.             <element ref="category" minOccurs="0" maxOccurs="1"/>      
  18.             <element ref="worklist" minOccurs="0" maxOccurs="1"/>      
  19.          </choice>      
  20.          <attribute name="point" type="string" use="required"><!--定义point-->      
  21.             <annotation>      
  22.                <documentation>                        
  23.                </documentation>      
  24.             </annotation>      
  25.          </attribute>      
  26.          <attribute name="id" type="string"><!--定义id-->      
  27.             <annotation>      
  28.                <documentation>                        
  29.                </documentation>      
  30.             </annotation>      
  31.          </attribute>      
  32.          <attribute name="name" type="string"><!--定义name-->      
  33.             <annotation>      
  34.                <documentation>                        
  35.                </documentation>      
  36.             </annotation>      
  37.          </attribute>      
  38.       </complexType>      
  39.    </element>      
  40.        
  41.   <!--定义category-->      
  42.    <element name="category">      
  43.       <complexType>      
  44.          <attribute name="name" type="string"><!--定义category/name-->      
  45.             <annotation>      
  46.                <documentation>                        
  47.                </documentation>      
  48.             </annotation>      
  49.          </attribute>      
  50.          <attribute name="id" type="string"><!--定义category/id。引用category时,必须指出应用的id,而name给出了一个可供显示的直观的名字-->      
  51.             <annotation>      
  52.                <documentation>                        
  53.                </documentation>      
  54.             </annotation>      
  55.          </attribute>      
  56.          <attribute name="parentCategory" type="string"><!--定义父category,也就是说我们的category可以嵌套形成树状结构-->      
  57.             <annotation>      
  58.                <documentation>                        
  59.                </documentation>      
  60.             </annotation>      
  61.          </attribute>      
  62.       </complexType>      
  63.    </element>       
  64.      
  65.    <!--定义worklist,注意大小写-->      
  66.    <element name="worklist">      
  67.       <complexType>      
  68.          <attribute name="name" type="string"><!--定义worklist/name,可供显示的直观的名字-->      
  69.             <annotation>      
  70.                <documentation>                        
  71.                </documentation>      
  72.             </annotation>      
  73.          </attribute>      
  74.          <attribute name="icon" type="string"><!--定义worklist/icon,可供显示的直观的图标-->      
  75.             <annotation>      
  76.                <documentation>                        
  77.                </documentation>      
  78.             </annotation>      
  79.          </attribute>      
  80.          <attribute name="category" type="string"><!--定义worklist/category,存放的category位置。如果引用嵌套形式的category,则采用 parent_id/child_id的形式 -->      
  81.             <annotation>      
  82.                <documentation>                        
  83.                </documentation>      
  84.             </annotation>      
  85.          </attribute>      
  86.          <attribute name="class" type="string"><!--定义worklist/class,实现功能的类名称-->      
  87.             <annotation>      
  88.                <documentation>                        
  89.                </documentation>      
  90.                <appInfo>      
  91.                   <meta.attribute kind="java"/>      
  92.                </appInfo>      
  93.             </annotation>      
  94.          </attribute>      
  95.          <attribute name="id" type="string" use="required"><!--定义worklist/id,唯一标志-->      
  96.             <annotation>      
  97.                <documentation>                        
  98.                </documentation>      
  99.             </annotation>      
  100.          </attribute>      
  101.       </complexType>      
  102.    </element>      
  103.    <!--以下内容为PDE自动生成,与我们的编程无关-->      
  104.    <annotation>      
  105.       <appInfo>      
  106.          <meta.section type="since"/>      
  107.       </appInfo>      
  108.       <documentation>      
  109.          [Enter the first release in which this extension point appears.]      
  110.       </documentation>      
  111.    </annotation>       
  112.      
  113.    <annotation>      
  114.       <appInfo>      
  115.          <meta.section type="examples"/>      
  116.       </appInfo>      
  117.       <documentation>      
  118.          [Enter extension point usage example here.]      
  119.       </documentation>      
  120.    </annotation>       
  121.      
  122.    <annotation>      
  123.       <appInfo>      
  124.          <meta.section type="apiInfo"/>      
  125.       </appInfo>      
  126.       <documentation>      
  127.          [Enter API information here.]      
  128.       </documentation>      
  129.    </annotation>       
  130.      
  131.    <annotation>      
  132.       <appInfo>      
  133.          <meta.section type="implementation"/>      
  134.       </appInfo>      
  135.       <documentation>      
  136.          [Enter information about supplied implementation of this extension point.]      
  137.       </documentation>      
  138.    </annotation>       
  139.      
  140.    <annotation>      
  141.       <appInfo>      
  142.          <meta.section type="copyright"/>      
  143.       </appInfo>      
  144.       <documentation>               
  145.       </documentation>      
  146.    </annotation>       
  147.      
  148. </schema>     

  这样我们就定义好了扩展的属性。
  然后在plugin.xml加入:
     

xml 代码
  1. <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添加了一个方法用以从注册表中读取扩展信息:
   

java 代码
  1. public IWorkListRegistry getWorkListRegistry() {   
  2.   if (workListRegistry == null) {   
  3.    workListRegistry = new WorkListRegistry();   
  4.    try {   
  5.     WorkListRegistryReader reader = new WorkListRegistryReader();   
  6.     reader.readWorkList(Platform.getExtensionRegistry(), workListRegistry);   
  7.    } catch (CoreException e) {   
  8.     // cannot safely show a dialog so log it   
  9.     WorkbenchPlugin.log("Unable to read workList registry.", e.getStatus()); //$NON-NLS-1$   
  10.    }   
  11.   }   
  12.   return workListRegistry;   
  13.  }   

其中WorkListRegistryReader.readWorkList定义如下:

java 代码
  1. /**  
  2.  * Read the workList extensions within a registry.  
  3.  */  
  4. public void readWorkList(IExtensionRegistry in, WorkListRegistry out)   
  5.  throws CoreException {   
  6.  // this does not seem to really ever be throwing an the exception   
  7.  workListRegistry = out;   
  8.  readRegistry(in, WorkListPlugin.getDefault().getPluginId(), "workList");   
  9.  out.mapWorkListToCategories();   
  10. }   

可见,我们不需要编写复杂的代码就可以读取注册表中存放的扩展信息!
  我们对workList扩展的显示是采用了TreeView,代码如下(WorkListView):
 

java 代码
  1.  protected TreeViewer createViewer(Composite parent) {   
  2.  TreeViewer viewer =   
  3.   new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);   
  4.   viewer.setUseHashlookup(true);   
  5.   viewer.setContentProvider(new WorkListContentProvider());   
  6.   viewer.setLabelProvider(new WorkListLabelProvider());   
  7.   workListReg = WorkListPlugin.getDefault().getWorkListRegistry();     
  8.   viewer.setInput(workListReg);   
  9.   initListeners(viewer);   
  10.   return viewer;   
  11. }   

这样,就可以实现显示了。
  那么,怎样实现选择某个扩展后,通过双击执行其功能呢?我们对TreeViewer添加了鼠标双击事件支持,关键代码如下:

java 代码
  1.  protected void handleDoubleClick(DoubleClickEvent event) {   
  2. IStructuredSelection selection = (IStructuredSelection) event.getSelection();   
  3. Object element = selection.getFirstElement();    
  4.   
  5. TreeViewer viewer = getWorkListViewer();   
  6. if (viewer.isExpandable(element)) {   
  7.  viewer.setExpandedState(element, !viewer.getExpandedState(element));      
  8. }else {   
  9.  WorkListDescriptor workList = (WorkListDescriptor)element;   
  10.  try {   
  11.    IWorkListPart workListPart = (IWorkListPart) workList.createWorkList();   
  12.    workListPart.run();   
  13.  } catch (CoreException e) {   
  14.   // should add something to handle the exception   
  15.  }   
  16. }    
  17.   
  18.   

其中IWorkListPart很简单,使所有实现workList扩展必须实现的接口:

java 代码
  1. public interface IWorkListPart {   
  2.     
  3.  public void run();    
  4.   
  5. }   
  6.   

只有一个run方法(可以自行添加其他的支持)。
  其中WorkListDescriptor.createWorkList方法实现根据class的字符串创建一个对象,也是超级简单,因为Eclipse已经为我们编好了:

java 代码
  1.  public Object createWorkList() throws CoreException {   
  2. Object obj = WorkbenchPlugin.createExtension(configElement, "class");   
  3. return  obj;   
  4.   

  这样就可以执行扩展的功能了。
  但是别忘了,还要编写pluin.xml,否则Eclipse可不认吆:

xml 代码
  1. <extension      
  2.          point="net.softapp.worklist.workList">      
  3.       <category      
  4.             name="HelloTest"     
  5.             id="HelloTest"/>      
  6.       <worklist      
  7.             icon="icons/example.ico"     
  8.             class="net.softapp.internal.worklist.Hello"     
  9.             category="HelloTest"     
  10.             name="Hello"     
  11.             id="net.softapp.internal.worklist.Hello"/>      
  12.    </extension>  

  
4.测试新扩展点
  
   OK,开始运行Eclipse的plugin调试环境,打开WorkList视图,看看在树状列表里是不是有一个HelloTest目录,下面有Hello。双击它,你编写的代码出来了吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值