自己動(dòng)手編寫Eclipse擴(kuò)展點(diǎn)
2024-07-21 02:14:06
供稿:網(wǎng)友
 
網(wǎng)站運(yùn)營seo文章大全提供全面的站長運(yùn)營經(jīng)驗(yàn)及seo技術(shù)!擴(kuò)展(extension)是eclipse中一個(gè)關(guān)鍵的機(jī)制,plug-in利用擴(kuò)展向eclipse平臺(tái)添加新功能。但是擴(kuò)展不能隨意地創(chuàng)建,必須按照擴(kuò)展點(diǎn)(extension point)定義的規(guī)范進(jìn)行明確的聲明,eclipse才能認(rèn)出這些擴(kuò)展。我們不僅可以使用eclipse提供的眾多現(xiàn)成的擴(kuò)展點(diǎn),而且還可以定義新的擴(kuò)展點(diǎn),并在該擴(kuò)展點(diǎn)上進(jìn)行擴(kuò)展。
 當(dāng)然,擴(kuò)展點(diǎn)的定義比較復(fù)雜。不過eclipse為用戶提供了圖形化的編輯界面,我們只要輸入一些信息,eclipse就會(huì)自動(dòng)生成代碼,使擴(kuò)展點(diǎn)的定義變得非常簡單。
 下面我們就來看看如何在eclipse中創(chuàng)建一個(gè)新的擴(kuò)展點(diǎn),并在這個(gè)擴(kuò)展點(diǎn)上進(jìn)行擴(kuò)展。
 我們需要做以下的工作:
1.設(shè)計(jì)該擴(kuò)展點(diǎn)
2.定義擴(kuò)展點(diǎn),即編寫擴(kuò)展點(diǎn)的清單文件
3.編寫代碼來載入該擴(kuò)展點(diǎn)的擴(kuò)展
 我們以創(chuàng)建worklist擴(kuò)展點(diǎn)為例,進(jìn)行詳細(xì)介紹。
 worklist完成的功能是:創(chuàng)建一個(gè)view,在其中以樹狀顯示系統(tǒng)中可用的功能模塊,通過雙擊某個(gè)模塊節(jié)點(diǎn),執(zhí)行該擴(kuò)展定義的方法(method)。其實(shí)相當(dāng)于一個(gè)控制臺(tái),通過控制臺(tái)來運(yùn)行不同的功能。
 由于eclipse是由一個(gè)運(yùn)行時(shí)核心(runtime core)和眾多插件組成的,我們也將worklist擴(kuò)展點(diǎn)定義在一個(gè)插件中,有關(guān)worklist的代碼文件也放在這個(gè)插件中,這樣便于查找和修改,也不影響eclipse本身的代碼。
 
1. 定義擴(kuò)展點(diǎn)
 首先我們要?jiǎng)?chuàng)建一個(gè)存放新擴(kuò)展點(diǎn)信息的插件net.softapp.worklist,這個(gè)插件對org.eclipse.ui.views進(jìn)行擴(kuò)展,以下是插件的plugin.xml文件在views擴(kuò)展點(diǎn)的信息:
 <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視圖”,打開視圖,我們用這個(gè)視圖顯示worklist擴(kuò)展點(diǎn)的所有擴(kuò)展信息。“show view”對話框顯示了eclipse中定義所有視圖,即所有org.eclipse.views擴(kuò)展點(diǎn)的擴(kuò)展。了解這一點(diǎn)很重要,因?yàn)槲覀冊诰帉憌orklist擴(kuò)展點(diǎn)代碼時(shí),就可以模仿甚至拷貝views擴(kuò)展點(diǎn)的代碼。
 下面,我們要在net.softapp.worklist插件中定義worklist擴(kuò)展點(diǎn)。
 擴(kuò)展點(diǎn)的定義文件按照eclipse的存放方式,一般存放在schema目錄下,我們把文件命名為worklist.exsd。內(nèi)容如下,此內(nèi)容由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"/>
 <!--通過這個(gè)定義,我們可以看出,定義的擴(kuò)展點(diǎn)的id是 net.softapp.worklist.worklist,以后引用時(shí)要注意,同時(shí)注意大小寫-->
 </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時(shí),必須指出應(yīng)用的id,而name給出了一個(gè)可供顯示的直觀的名字-->
 <annotation>
 <documentation> 
 </documentation>
 </annotation>
 </attribute>
  <attribute name="parentcategory" type="string"><!--定義父category,也就是說我們的category可以嵌套形成樹狀結(jié)構(gòu)-->
 <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,可供顯示的直觀的圖標(biāo)-->
 <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,實(shí)現(xiàn)功能的類名稱-->
 <annotation>
 <documentation> 
 </documentation>
 <appinfo>
 <meta.attribute kind="java"/>
 </appinfo>
 </annotation>
 </attribute>
 <attribute name="id" type="string" use="required"><!--定義worklist/id,唯一標(biāo)志-->
 <annotation>
 <documentation> 
 </documentation>
 </annotation>
 </attribute>
 </complextype>
 </element>
 <!--以下內(nèi)容為pde自動(dòng)生成,與我們的編程無關(guān)-->
 <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>
 這樣我們就定義好了擴(kuò)展的屬性。
 然后在plugin.xml加入:
 <extension-point id="worklist" name="worklist" schema="schema/worklist.exsd"/>
 就定義好了!
 
2. 實(shí)現(xiàn)擴(kuò)展
 定義完擴(kuò)展之后,接下來要編寫解析此擴(kuò)展的相關(guān)代碼。可喜的是,eclipse為我們提供了大量的api可以調(diào)用,省下了若干代碼的編寫。另外我們還可以借鑒eclipse實(shí)現(xiàn)的其他代碼,通過模仿來編寫我們自己的解析代碼。本例參考了view的解析部分。同view,我們定義了worklistdescriptor,worklistregistry,worklistregistryreader.其中worklistdescriptor完成對上述定義的解析,worklistregistry存放了其他插件對worklist擴(kuò)展的相關(guān)信息,worklistregistryreader則從worklistregistry讀取信息供我們使用。
 此處代碼從略,具體請參考view實(shí)現(xiàn)部分的viewdescriptor,viewregistry,viewregistryreader相關(guān)代碼。
 
3. 編寫界面部分
 根據(jù)1對view的擴(kuò)展,我們需要編寫界面部分。此處請參考view插件的編寫。我們在此對worklistplugin添加了一個(gè)方法用以從注冊表中讀取擴(kuò)展信息:
 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();
}
可見,我們不需要編寫復(fù)雜的代碼就可以讀取注冊表中存放的擴(kuò)展信息!
 我們對worklist擴(kuò)展的顯示是采用了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;
 }
這樣,就可以實(shí)現(xiàn)顯示了。
 那么,怎樣實(shí)現(xiàn)選擇某個(gè)擴(kuò)展后,通過雙擊執(zhí)行其功能呢?我們對treeviewer添加了鼠標(biāo)雙擊事件支持,關(guān)鍵代碼如下:
 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很簡單,使所有實(shí)現(xiàn)worklist擴(kuò)展必須實(shí)現(xiàn)的接口:
public interface iworklistpart {
 
 public void run();
}
只有一個(gè)run方法(可以自行添加其他的支持)。
 其中worklistdescriptor.createworklist方法實(shí)現(xiàn)根據(jù)class的字符串創(chuàng)建一個(gè)對象,也是超級簡單,因?yàn)閑clipse已經(jīng)為我們編好了:
 public object createworklist() throws coreexception {
 object obj = workbenchplugin.createextension(configelement, "class");
 return obj;
 }
 這樣就可以執(zhí)行擴(kuò)展的功能了。
 但是別忘了,還要編寫pluin.xml,否則eclipse可不認(rèn)吆:
 <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.測試新擴(kuò)展點(diǎn)
 
 ok,開始運(yùn)行eclipse的plugin調(diào)試環(huán)境,打開worklist視圖,看看在樹狀列表里是不是有一個(gè)hellotest目錄,下面有hello。雙擊它,你編寫的代碼出來了吧!