快速掌握Eclipse Plugin / RCP開發思想java
李曉明 (lxm@lxm.name)程序員
本文不是快速入門的文章,只面向有必定基礎的開發人員,至少看這篇文章以前你應該瞭解什麼是Eclipse,什麼是RCP,什麼是Plugin,什麼是架構,什麼是軟件框架等等概念。不然的話這篇文章也幫不了你什麼。另外,本人對RCP的理解也是處於只知其一;不知其二的程度,若有錯誤還請指出。算法
Eclipse是一種面向開發人員的編程環境(IDE),同時它也是一個很好的平臺,它提供了一種架構,或者說一種軟件框架,可讓開發人員相對比較容易的開發出功能比較強大的,帶有人機交互功能的應用程序。編程
Eclipse這種強大的功能是經過其插件(Plugin)來實現的,RCP也是如此。RCP的全稱是Rich Client Platform,其根本就是把Eclipse的應用平臺剝離了其餘的插件以後剩下的東西,天然其架構和原理與eclipse自己是同樣的。RCP也能夠經過插件來進行擴展,但RCP每每是用來開發一些像Eclipse同樣獨立的應用程序。架構
本文幫助對RCP不是很清楚的人快速的理解Eclipse RCP和Plugin的工做原理與開發方法。框架
讓咱們閉上眼睛靜下心來冥想一下,咱們能夠想象,若是要開發一個帶有人機交互的應用程序,必備的幾個部分是什麼?eclipse
1 人機界面。人機界面在某些應用程序中基本上就能夠當成是軟件的核心了,特別是一些輕量級的應用中。VB這方面作的就很好,它基本上就是一個以界面爲核心的開發環境,我曾經在上課的時候講過,VB編程基本上就兩步,第一步畫好界面,第二步寫界面的響應代碼(事件處理程序)。這個思路基本上能夠解決百分之八十的Vb編程應用。人機界面其實是人機交互的一部分,它能夠將各類數據用圖形化的方法呈現給操做者。雖然有人會認爲人機界面還應當包括用戶對界面操做所做出的響應,例如用戶在用鼠標點擊按鈕時按鈕的按下效果等,但這本質上仍是屬於可視界面的範疇,並且是提早預約好的,並非一種真正的交互。編輯器
2 數據模型。這在應用程序中是相當重要的,由於界面所顯示的內容主要是從數據模型中獲取的,另外用戶經過界面錄入的數據也是要存儲到數據模型中去的。這也是軟件存在目的之一,獲取數據,管理數據和修改數據等。對於數據和數據模型,通常的程序員都有着深入的理解,這裏就不贅述了。不是一度計算機軟件被宣稱等於數據加算法的嗎?ide
3 用戶命令輸入。人機交互的另外一部分,即用戶能夠經過人機界面輸入(或者釋放)相應的命令。在目前的人機交互模型中,用戶命令的輸入一般是經過一些控件來實現的,例如按鈕,文本框,快捷鍵,菜單等。在觸摸界面中還包括手勢,在智能系統中甚至包括語音等。工具
4 業務邏輯。這是軟件的主要功能,也是用戶需求的集中體現。業務邏輯一般是用戶命令激發的,包括對數據進行分析和處理,並得到新的可供展現的數據的過程。固然也有一些業務邏輯是在後臺執行的。
用圖形的方式來展現這四個部分的功能:
你們都是作軟件開發的,不知道你們有沒有想過,這四個部分實際上是能夠作到相互之間是獨立的。其實你們都知道有一個著名的MVC模型(Model-View-Control)模型和這個基本上是同樣的。可是MVC我一直以來也沒有搞明白其中的Control是什麼功能,因此我認爲我上面提出的四個部分的功能分解是比較好理解的。
在Eclipse的框架裏,因爲Eclipse是面向人機交互的,因此在框架裏是不包含數據模型這一塊的,業務邏輯這塊也只包括用戶命令處理這一部分,其框架的大部分功能都集中在人交互這塊。用圖形表述一下是這樣的:
接下來介紹一下Eclipse裏的經常使用到的術語。
首先看一下界面部分。下圖是Eclipse應用程序的界面。
界面最外面的叫作Workbench Window。也是應用程序最頂層的界面模塊。通常來講一個應用會有一個Workbench Window,不過根據Eclipse的手冊說明,其實也能夠有多個Workbench Window,可是怎麼實現還不清楚,目前接觸的例子都是單窗口的。
Workbench Window包含了主菜單(Menu Bar),工具條(Tool Bar),狀態條(Status Bar)和一個頁面Page。這些都是典型的GUI程序鎖必備的。
頁面Page是應用程序窗口的主界面,也是工做區界面。Page裏包括各類的View和Editor,View,Editor都稱爲Part。因此View也稱爲ViewPart,Editor也稱爲EditorPart。View和Editor的區別在於:View一般是用來顯示目錄樹,屬性窗口,文檔結構圖等相似內容,能夠把View當作是數據在某個功能界面上的反映,並且View所作的修改會馬上生效。Editor顧名思義是用來編輯文檔的,或者修改文檔內容的,Editor所作的修改必需經過專門的保存命令進行存儲生效。在Editor界面關閉的時候會檢查文檔內容是否爲「髒」,並提示用戶保存爲「髒」的文檔。除此以外,二者太大的區別。
在編程行爲上看,editor和View最大區別就是:同一類(來自同一個類)的View在界面中只能有一個,而同一類的Editor能夠有多個,可是同一個文檔只能打開一個對應的Editor。
Eclipse的插件開發全靠擴展點這個玩意了。擴展點顧名思義就是開發者能夠對原程序進行功能和界面擴展的地方。
個人理解,擴展點就是應用程序留下來的插座,擴展程序經過使用擴展點,能夠把本身編寫的代碼接入到原有程序中。可是不一樣的擴展點,能夠接入的東西是不同的,須要程序員仔細體會。從Java程序開發的角度來看,只要寫的類使用了約定的接口,就能夠被平臺類加載和調用。從這個意義上來說,擴展點接入的實際上不是代碼,而是對接入代碼的描述。經過擴展點接入的聲明,能夠告訴Eclipse平臺,使用什麼功能的時候調用什麼類,新的插件提供了哪些功能,或者擴展了原有的哪些功能等。從這個意義上將,擴展點本質上是配置信息。
RCP中的擴展點很是多,並且RCP甚至還容許開發者建立新的擴展點!因此,這裏咱們只給你們介紹一下RCP中的基本的擴展點。
須要說明的是,RCP中強調的是儘可能的少寫代碼。特別是界面這塊,所以,大部分的界面相關的東西都是能夠經過擴展點實現的。固然有不少功能用代碼也能夠實現,可是簡單的用XML配置文件就能夠實現一個界面豈不是更好嗎?
這個擴展點定義了系統當中的全部的View。
<extension
point = "org.eclipse.ui.editors">
<editor
class="org.eclipse.ui.examples.contributions.editor.InfoEditor"
icon="icons/editor.gif"
id="org.eclipse.ui.examples.contributions.editor"
name="%contributions.editor.name">
</editor>
</extension>
Category主要用於分類參數配置。Eclipse有本身專門的參數設置界面,屬於同一個Category的類會出如今同一個設置面板中,其餘沒有什麼做用。
這裏能夠用本身寫的View,也能夠用別人已經寫好的View,class這個選項的值指向的是具體運行這個視圖的類。這個View的代碼須要本身寫,必需繼承ViewPart這個虛擬類或者實現IViewPart這個接口。
這個擴展點下面要給出軟件系統中全部的Editor。
<extension
point = "org.eclipse.ui.editors">
<editor
class="org.eclipse.ui.examples.contributions.editor.InfoEditor"
icon="icons/editor.gif"
id="org.eclipse.ui.examples.contributions.editor"
name="%contributions.editor.name">
</editor>
</extension>
Editor有本身特有的一些屬性,例如extension屬性,能夠指定editor可以打開的文件類型等。對於某些不須要編輯器的應用,能夠忽略這部份內容,由於大部分的不須要編輯器的應用實際上不須要Editor,只須要View。
這個擴展點裏面收集了大量的命令。以前一節講到了命令這個概念,你們千萬不要誤會這裏的命令。這裏的命令指的是用戶能夠經過界面產生的命令,可是這裏的命令是沒有實現的。也就是說,你能夠在這裏本身定義大量的命令,但能夠本身不實現,等待後續有人寫新的擴展來實現你制定的命令。固然,絕大多數咱們寫的程序不會指望別人來幫咱們寫代碼,本身仍是要寫代碼來實現這裏的命令的,可是咱們寫的代碼不會在這裏有體現,而是體如今後面要講的handler裏。
<extension
point="org.eclipse.ui.commands">
<command
categoryId="org.eclipse.ui.examples.contributions.commands.category"
id="org.eclipse.ui.examples.contributions.view.count"
description="%contributions.view.count.desc"
name="%contributions.view.count.name">
</command>
<category
name="%contributions.commands.category.name"
description="%contributions.commands.category.desc"
id="org.eclipse.ui.examples.contributions.commands.category">
</category>
</extension>
這個擴展點對於我們編程序的人來講過重要了。前面咱們剛看到了command,會疑惑說,command實際上就是一個花架子,其實什麼都不作,這樣子弄個command什麼用處呢?用處太大了。Command比如定義了用戶的一條指令,比方說在View上弄個曲線什麼的。可是這個指令怎麼發出的呢?Command這個擴展點並無說明,緣由就是要留到這裏說。Menus這個擴展點裏要定義的,就是用戶的Command如何發出的問題。
通常狀況下,用戶的command主要經過人機界面發出,經常使用到的控件爲菜單,工具條,快捷鍵等。快捷鍵暫且不表,這裏主要定義了菜單(各類類型)以及工具條。
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="menu:org.eclipse.ui.examples.contributions.view?after=additions">
<command
commandId="org.eclipse.ui.examples.contributions.view.count"
mnemonic="%contributions.view.count.mnemonic">
</command>
<command
commandId="org.eclipse.ui.examples.contributions.view.edit"
mnemonic="%contributions.view.edit.mnemonic">
</command>
<command
commandId="org.eclipse.ui.file.refresh"
mnemonic="%contributions.view.refresh.mnemonic">
</command>
</menuContribution>
...
一個MenuContribution就定義了一個菜單。Command標籤訂義了菜單對應的命令。經過這些文本,就將菜單與命令結合了起來。Command裏的label屬性定義了菜單的標籤,天然也能夠定義圖標,菜單的屬性(push,仍是radio),以及tooltip等。
其中一個很重要的屬性是locationURI。它定義了菜單在什麼地方顯示。下面幾個例子有所說明:
menu:org.eclipse.ui.main.menu?after=window
在主菜單中插入菜單
menu:file?after=additions
同上
menu:org.eclipse.ui.views.ContentOutline?after=additions
在View上顯示菜單(又叫作快捷菜單)
toolbar:org.eclipse.ui.views.ContentOutline?after=additions
在View上的工具條位置上顯示菜單(其實是工具按鈕)
popup:org.eclipse.ui.examples.propertysheet.outline?after=additions
在某個View上顯示彈出菜單(右鍵菜單)
可見,經過上述方法,能夠定義任意地方上的菜單,工具條等。關鍵的一點是,你不須要寫任何代碼,很是的爽。
儘管在界面上放置菜單是不須要寫任何代碼的,可是對命令的處理時必需要寫代碼的,這個時候就須要handler擴展了。
Handler是對命令的實現。能夠放在這裏:
<command categoryId="org.eclipse.ui.examples.contributions.commands.category"
defaultHandler="org.eclipse.ui.examples.contributions.handlers.GlobalMenuHandler"
id="org.eclipse.ui.examples.contributions.commands.globalCommand"
name="%contributions.commands.globalCommand.name">
</command>
也能夠放在這裏:
<handler
class="org.eclipse.ui.examples.contributions.handlers.GlobalMenuHandler"
commandId="org.eclipse.ui.examples.contributions.commands.globalCommand">
</handler>
無非就是將實現類與commandid關聯起來。這個實現類必需要繼承AbstractHandler或者實現IHandler接口。
須要說明的是,一個命令能夠有多個Handler,由於每一個handler有本身的scope(做用域),通常說來,越具體的UI組件所實現的Handler具備越高的優先級。不過這個屬於比較高級的話題,感興趣的能夠去研究一下Eclipse的幫助文檔。(注:此段可能有誤)
這裏簡明扼要的介紹一個RCP應用程序的開發方法,相似介紹網上較多,能夠去搜索學習。
通常狀況下利用嚮導獲得的應用程序,代碼裏包括這麼幾個文件:
Application.java這個文件裏包括了應用程序的一些信息,包括啓動界面和關閉界面。若是你須要在打開界面的時候作一些事情(例如讓用戶輸入驗證密碼等),能夠在這個文件裏進行處理。
ApplicationWorkbenchAdvisor.java這個文件用來配置平臺的一些信息。這個裏面一個重要的方法是返回默認的Perspective。
ApplicationWorkbenchWindowAdvisor.java這個文件用來配置窗口的一些屬性的。
ApplicationActionBarAdvisor.java是用來配置工具欄的。
最重要的是配置plugin.xml這個文件。Eclipse提供了各類的輔助工具來編輯這個文件,裏面最重要的是這個extensions標籤。這個能夠用右鍵添加各類item。最重要的是用來編輯menus,views,commands和handlers。其屬性在前面已經介紹過了,若是有不明白的能夠查閱幫助。