分享
 
 
 

自己动手编写Eclipse扩展点

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

扩展(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。双击它,你编写的代码出来了吧!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有