GUI桌面編程這個(gè)話題本來(lái)就非常不好寫(xiě)。這么多年,這么大一個(gè)領(lǐng)域,真真正正能寫(xiě)成像《深入淺出MFC》這樣的經(jīng)典的書(shū)籍沒(méi)有幾本。縱觀國(guó)內(nèi)在該領(lǐng)域出版的書(shū)籍,要么就是大篇大篇羅列這個(gè)控件那個(gè)控件怎么用,控件有哪些屬性可以設(shè)置,有哪些事件可以處理;要么就是大段大段貼代碼,而對(duì)于GUI編程的一些本質(zhì)、一些哲學(xué)性的東西沒(méi)有深入的分析。在Eclipse RCP領(lǐng)域尤其如此,有那么幾本打著Eclipse RCP和OSGi大旗的書(shū)籍,但是其參考價(jià)值卻不比Eclipse自帶的幫助文檔大多少,大有圈錢(qián)的嫌疑。
Eclipse RCP是個(gè)好東西。用Eclipse RCP寫(xiě)桌面程序,可以在一個(gè)很高的起點(diǎn)上構(gòu)建自己的窗口應(yīng)用,至于那種從頭開(kāi)始寫(xiě)窗口的日子是再也不復(fù)返了,甚至美工都不需要自己考慮了。(想想VC領(lǐng)域有多少界面庫(kù)在折磨著程序員。)還有一個(gè)好處當(dāng)然是跨平臺(tái)了,雖然要背上一個(gè)Java虛擬機(jī)的負(fù)擔(dān)。(現(xiàn)在的Eclipse RCP程序?qū)С鰰r(shí)可以自己包含JRE,又大大簡(jiǎn)化了程序部署的過(guò)程。)
五年前我寫(xiě)的那幾篇博文有很多缺點(diǎn),缺點(diǎn)一是其中有些東西我自己都沒(méi)有搞懂,所以沒(méi)辦法寫(xiě)得太深入;缺點(diǎn)二是跳躍性太大,總共才六篇,我卻又是展示COM組件,又是展示OpenGL,雖說(shuō)讓大家在視覺(jué)上是狠狠體驗(yàn)的一把,但是一點(diǎn)也不系統(tǒng)。所以這次一定要改變這些缺點(diǎn),爭(zhēng)取做到以下目標(biāo):
目標(biāo):
1.言簡(jiǎn)意賅,對(duì)于那些有助于理解Eclipse RCP平臺(tái)的核心概念重點(diǎn)點(diǎn)出,并結(jié)合實(shí)例。對(duì)于那種在Google上一查一大把的廢話堅(jiān)決不寫(xiě);
2.爭(zhēng)取系統(tǒng)性地介紹Eclipse RCP平臺(tái)可用的特性及其背后的一些設(shè)計(jì)模式,不再浮光掠影地一飄而過(guò),也不專(zhuān)寫(xiě)冷門(mén)偏門(mén);
3.不追求面面俱到,有些用不到的東西肯定沒(méi)必要講,也不怕別人說(shuō)我水平差;
4.當(dāng)然是大量展示圖片啦。
好了,下面開(kāi)工,首先,當(dāng)然是創(chuàng)建一個(gè)Hello World,初步展示一些Eclipse RCP的效果。Eclipse RCP編程的本質(zhì)就是利用Eclipse的插件機(jī)制,在Eclipse的Runtime上進(jìn)行擴(kuò)展來(lái)構(gòu)建我們自己的窗口程序,所以,創(chuàng)建項(xiàng)目的時(shí)候當(dāng)然是創(chuàng)建一個(gè)Plug-in Project了。只是在下面那個(gè)“Would you like to create a rich client application ?”的地方選擇yes即可。
一路Next下去,我就不多截圖了。在選擇應(yīng)用程序模板的時(shí)候,選擇最簡(jiǎn)單的Hello RCP即可。如果這時(shí)運(yùn)行程序(用Run As -> Eclipse Application),可以得到一個(gè)簡(jiǎn)單的窗口。
為了顯示Hello World,我們需要一個(gè)擴(kuò)展一個(gè)View。創(chuàng)建一個(gè)View類(lèi),其基類(lèi)為org.eclipse.ui.part.ViewPart,如下圖:
在HelloWorldView的代碼中,我們只需要一個(gè)SWT中的Label控件用來(lái)顯示HelloWorld,如下圖:
下一步,就要把這個(gè)HelloWorldView插入到窗口中,這個(gè)可以通過(guò)配置Plugin的Extension來(lái)實(shí)現(xiàn)。打開(kāi)plugin.xml的編輯器,增加一個(gè)org.eclipse.ui.views的擴(kuò)展,如下圖:
在Eclipse中,擴(kuò)展的View并不是馬上顯示到前臺(tái),而是要通過(guò)菜單Window->Show View來(lái)顯示,或者將View關(guān)聯(lián)到某個(gè)透視圖,切換透視圖的時(shí)候顯示這個(gè)View。我們的RCP程序的目標(biāo)是單獨(dú)運(yùn)行,而不是當(dāng)插件安裝到Eclipse中,追求的是一運(yùn)行程序就顯示這個(gè)View,所以還要擴(kuò)展org.eclipse.ui.perspectiveExtensions。如下圖:
運(yùn)行程序,看看效果。通過(guò)Run As -> Eclipse Application運(yùn)行,如下圖:
到現(xiàn)在,我們的工作完成一半,因?yàn)樵摮绦蜻€只能在Eclipse中運(yùn)行,要想脫離Eclipse單獨(dú)運(yùn)行,必須將其作為單獨(dú)的產(chǎn)品導(dǎo)出。要導(dǎo)出產(chǎn)品,先要新建一個(gè)product configuration,然后進(jìn)行配置。為簡(jiǎn)單起見(jiàn),我們只需要配置三個(gè)地方。
第一個(gè)地方:Application,這個(gè)關(guān)系到程序的啟動(dòng)點(diǎn)
第二個(gè)地方,launcher,這個(gè)可以生成一個(gè)像eclipse那樣的本地啟動(dòng)程序
第三個(gè)地方,依賴(lài)項(xiàng),可以先把自己添加到依賴(lài)項(xiàng)中,然后再點(diǎn)Add Required Plug-ins按鈕添加所有需要的依賴(lài)項(xiàng)
我自己第一次接觸Eclipse RCP時(shí),就經(jīng)常因?yàn)椴话炎约禾砑拥揭蕾?lài)項(xiàng)中而造成程序啟動(dòng)失敗。
下一步,導(dǎo)出程序,如下圖:
在以上對(duì)話框中,我把能省的空都省了。最后得到的目標(biāo)程序文件夾內(nèi)容及運(yùn)行程序的效果如下圖:
以上過(guò)程非常簡(jiǎn)單,所以先秀圖片。下面,來(lái)看看Eclipse RCP和OSGi的一些概念。
1.Bundle和Bundle的生命周期:Bundle是OSGi的一個(gè)概念,我們可以把它理解為模塊、插件,如果僅僅只是學(xué)習(xí)Eclipse RCP編程的話,就不需要對(duì)OSGi進(jìn)行深入學(xué)習(xí),雖然它很流行。但是一些基本的概念還是要知道的。Eclipse完全構(gòu)建在OSGi之上,它包含有一個(gè)OSGi規(guī)范的完整實(shí)現(xiàn)Equinox。所以Eclipse的一個(gè)Plug-in,基本上就等于OSGi的一個(gè)Bundle。我們不需要特意去編輯Bundle的定義文件META-INFO/MANIFEST.MF,在編輯plugin.xml的時(shí)候,Bundle的定義文件會(huì)自動(dòng)更新。一個(gè)Bundle被安裝到OSGi系統(tǒng)中后,并不會(huì)馬上啟動(dòng),只有當(dāng)這個(gè)Bundle提供的功能被調(diào)用的時(shí)候,該Bundle才會(huì)被啟動(dòng),當(dāng)該Bundle不被用到的時(shí)候,它就可以被停止。在一個(gè)Bundle的生命周期中,我們可以定義自己的Activator來(lái)處理啟動(dòng)、停止等各個(gè)階段的任務(wù),這就是我們前面的例子中為什么要定義一個(gè)Activator的原因。通過(guò)Activator,我們可以查看OSGi系統(tǒng)中安裝的所有Bundle,因?yàn)镺SGi系統(tǒng)調(diào)用Activator中的方法時(shí),會(huì)傳遞一個(gè)BundleContext參數(shù),使用該context,我們可以完全訪問(wèn)整個(gè)OSGi系統(tǒng)的功能。
2.Plug-in之間或Bundle之間的依賴(lài)關(guān)系:由于Plug-in和Bundle基本上是同義詞,所以在后文中我將不提Bundle。Eclipse的Plug-in機(jī)制早已深入人心,一個(gè)Plug-in經(jīng)常會(huì)依賴(lài)于其它的Plug-in,這已經(jīng)成為常識(shí),不需要我贅述。Plug-in的定義中最重要的就是它的ID和Version,靠這兩個(gè)字段就可以唯一標(biāo)識(shí)一個(gè)Plug-in,所以在前面的例子中,凡是出現(xiàn)ID的地方,我都很認(rèn)真填寫(xiě),并且使用com.xkland.....這樣的形式來(lái)定義ID,避免出現(xiàn)沖突。對(duì)于Name、Vendor這樣的字段,明顯是給人閱讀的,所以就隨便填一填。
3.還有比Plug-in更小的單位,那就是Package:雖然說(shuō)Eclipse中的Plug-in是一個(gè)很小的單位了,但是還有更小的,那就是Package。如果有人不想依賴(lài)整個(gè)Plug-in的話,也可以單獨(dú)只Import幾個(gè)Package。當(dāng)然,對(duì)于我們自己寫(xiě)的Plug-in,也可以export一些Package供別人使用。在plugin.xml的編輯器中,有一個(gè)專(zhuān)門(mén)的頁(yè)面是用來(lái)設(shè)置和Package相關(guān)的內(nèi)容的。在前面的例子中沒(méi)有演示這一點(diǎn),因?yàn)槲矣X(jué)得我寫(xiě)的程序還沒(méi)有必要分這么細(xì)。
4.Extension和Extension Point:這個(gè)好像也早就是Eclipse領(lǐng)域常識(shí)性的概念了吧。在Plug-in中可以定義一些Extension Point,在別的Plug-in中可以擴(kuò)展這些Extension Point。比如在前面的例子中,我們自己的Plug-in擴(kuò)展了org.eclipse.core.runtime插件(叫Bundle可能更合適)和org.eclipse.ui插件定義的幾個(gè)擴(kuò)展點(diǎn),這些定義實(shí)在plugin.xml編輯器的Extensions頁(yè)面定義的。當(dāng)然,我們的程序沒(méi)有定義自己的Extension Point,因?yàn)椴恍枰寗e人去擴(kuò)展什么。
5.Product不是個(gè)什么重要的概念,從前面的例子可以看出,我們定不定義Product的ID都沒(méi)什么影響。不過(guò)要導(dǎo)出Product的時(shí)候,application一定要指定,依賴(lài)項(xiàng)也要搞清楚,因?yàn)檫@關(guān)系到我們的程序能不能成功運(yùn)行。
好了,概念性的東西就將這么多。OSGi不需要深究,因?yàn)槲覀儠?huì)直接和Eclipse的Runtime打交道,以后會(huì)有專(zhuān)門(mén)的章節(jié)講Eclipse的Runtime提供有哪些服務(wù)。下面的例子演示即使不使用Native launcher,也可以通過(guò)OSGi框架啟動(dòng)我們的Hello World。
在導(dǎo)出Product的時(shí)候,選擇如下圖中的單選框和填寫(xiě)好根目錄:
就可以得到一個(gè)Repository,該Repository是供p2安裝程序使用的,里面沒(méi)有Native launcher。如下圖:
在這個(gè)目錄里面建立一個(gè)configuration文件夾,里面放一個(gè)config.ini,記住,在Linux系統(tǒng)下,configuration文件夾一定要是rwx權(quán)限的哦。config.ini文件內(nèi)容如下:
該文件定義了OSGi啟動(dòng)時(shí)安裝哪些Bundle,并且這些Bundle默認(rèn)的啟動(dòng)級(jí)別是多少。啟動(dòng)級(jí)別的數(shù)字越小的越優(yōu)先啟動(dòng)。configuration/config.ini是OSGi啟動(dòng)時(shí)默認(rèn)的配置文件路徑,當(dāng)然也可以使用-configuration選項(xiàng)更改為別的路徑。然后,如下命令啟動(dòng)HelloWorld:
在指定啟動(dòng)OSGi的jar文件時(shí),我偷了點(diǎn)懶,為了少敲幾下鍵盤(pán),使用了一個(gè)通配符,大家還是可以很輕松地看出來(lái)是哪個(gè)文件哦?Equinox的官方文檔在這里:http://eclipse.org/equinox/documents/quickstart-framework.php
如果想按照Equinox的官方文檔啟動(dòng)OSGi框架的命令行,還得從Eclipse的安裝目錄找到如下幾個(gè)文件:
然后還需要這樣一個(gè)config.ini文件:
從Hello World這個(gè)例子可以看出,我們的Eclipse RCP程序構(gòu)建在org.eclipse.core.runtime和org.eclipse.ui這兩個(gè)Bundle上。下一篇,我將為大家講述這兩個(gè)Bundle能為我們提供哪些服務(wù)。
新聞熱點(diǎn)
疑難解答
圖片精選