摘自:http://book.csdn.net/bookfiles/493/10049317083.shtml
從本章開始,將帶領大家進入激動人心的Eclipse RCP開發之旅。本章先將經費測算系統的架子搭建起來,例如菜單、工具欄、主控界面等等,至于系統各功能的實現細節,在隨后的章節中將層層剝開。為了節省篇幅,從本章開始,對于大量需要導入的類,在程序代碼中將予以省略。
本章將主要學習到以下技術實現:
l 創建RCP項目。
l 定制開發平臺和目標平臺。
l 定制窗口屬性。
l 添加菜單和工具欄。
l 實現主界面透視圖、視圖。
l 實現系統托盤。
l 定時自動顯示托盤氣泡提示文本。
l 圖片的緩沖處理。
l 品牌化應用程序。
5.1 新建RCP項目
為了方便后面工作,可先將以前所做的test項目刪除。在test項目上點擊鼠標右鍵,選擇【Delete】,在彈出的“Confirm Project Delete”對話框中單擊【Yes】按鈕即可。如果要徹底刪除,請選擇“Also delete contents under ‘c:"jfcs_workspace"test’”。
在新建RCP項目之前,先設置一下整個Eclipse系統默認文件輸出組織方式。選擇主菜單【Window】→【Preferences…】,在彈出的“Preferences”對話框中展開Java,選中Build Path,在Source and output folder下單選Folders,再單擊【Apply】按鈕(一定要單擊此按鈕,而不是直接單擊【OK】按鈕),如圖5-1所示。這樣設置的目的是將源文件和編譯后的class目標文件分開存放,以方便管理。
圖5-1 項目輸出路徑設置
5.1.1 創建經費測算項目
創建RCP項目時,Eclipse提供了向導方式,并內置了3種RCP模板,整個工作簡單而又輕松,具體步驟如下:
(1)單擊鼠標右鍵,選擇【New】→【Project…】,在彈出的對話框中選擇【Plug-in Project】,單擊【Next】按鈕,在Project name后輸入項目名稱cn.edu.jfcs。項目名稱習慣上命名為公司域名+產品名稱的倒序,這樣可以比較好的避免與他人產品名稱重復。例如:cn.edu.hust.gzgl,表示華中科技大學工資管理系統項目。
單擊【Next】按鈕,彈出如圖5-2所示的對話框,要求用戶指定ID、Version、Name等信息。Plug-in Provider可以輸入作者名稱或者公司名稱。Classpath要求指定類文件夾名稱,一般針對插件項目,對于RCP項目來說,可以不指定。不需要勾選Plug-in Options下的“Generate an activator, a Java class that controls the plug-in’s life cycle”,對于RCP來說并不需要生成一個激活器類來控制插件的生命周期。選中Rich Client Application中的Yes。
圖5-2 插件配置
(2)單擊【Next】按鈕,Eclipse提供了3種RCP模板以供選擇。選中“RCP application with an intro”模板。該模板啟動時會帶有歡迎畫面。
(3)單擊【Next】按鈕,彈出“New RCP Project with an intro”對話框。將Product Name修改成jfcs,其他不需要修改。單擊【Finish】按鈕,項目創建完成。
現在修改一下項目的包名。展開項目src文件夾,向導默認創建的包名為cn.edu.jfcs.intro,這個包名的含義有些含混不清,并不是希望的結果。將該包名修改成更有意義的cn.edu.jfcs.app似乎更好。修改包名需要用到Eclipse的重構(Refactor)功能。
重構簡單說來就是將程序中的元素,例如某個類,重新命名,并自動更新相關的應用。設想一下,如果希望將某個類重新命名,但這個類可能在很多地方引用,如果沒有重構功能,得到全部類中搜尋,這項工作不但費力而且痛苦不堪,關鍵是辛苦半天可能還有遺漏!Eclipse的重構功能受到了開發人員的熱烈歡迎,一個常用的例子是Rename重構,Rename重構可以對屬性、變量、類以及接口等重新命名,并自動更改全部引用而不會遺漏。實際上Rename重構只是Eclipse重構的一種,Eclipse重構還可以實現將一個類中的方法或者屬性移到子類或者父類中,或者改變類內部的代碼,例如將某個方法中的代碼抽取出來變成一個獨立的方法。善用重構功能,可以減輕一定的編程工作量。
在包名cn.edu.jfcs.intro上單擊鼠標右鍵,選擇【Refactor】→【Rename…】,彈出“Rename Package”對話框,在New name后的文本框中輸入新包名cn.edu.jfcs.app,單擊【OK】按鈕即可。
現在可以試運行經費測算程序,體驗一下RCP程序。單擊如圖5-3所示的項目Overview概覽視圖中的“Launch an Eclipse application”,將首先彈出splash閃屏畫面,然后顯示如圖5-4所示的系統主界面。該界面自帶了Help菜單,并有一個簡單的Welcome歡迎界面。
圖5-3 項目概覽視圖 圖5-4 項目運行主界面
項目的運行實際上還有更快捷的方式。單擊如圖5-5所示的工具欄Run 圖標按鈕,即可運行jfcs項目。注意到,該運行圖標按鈕的提示文本是“Run Eclipse Application”,換成有意義的提示更好。因為一旦項目很多,工具按鈕的提示文本就可能使人不得要領。選擇系統菜單的【Run】→【Run…】,在彈出對話框的Name文本框中輸入“jfcs”,單擊【Apply】按鈕,再單擊【Close】?,F在鼠標指向Run圖標按鈕,提示文本變為“Run jfcs”。
圖5-5 工具欄Run圖標按鈕
5.1.2 項目的組織結構
在第1章曾經討論到,Eclipse RCP基于組件架構,該組件架構的最基本單元被稱之為插件(Plug-in),插件則通過插件擴展點(Extension point)定義。在Eclipse里面,“萬物皆插件”。所謂的RCP,不過是插件及其支撐內核的集合而已,只不過最后需要打包成產品發布。開發者只需要在Eclipse內核基礎上,定義并實現一個一個的插件,就可以組裝成RCP。所以,在前面創建經費測算項目時,選擇“Plug-in Project”,也就不足為怪了。也就是說,高校經費測算項目實際上就是一個大的插件!你可以認為Eclipse是花瓶,插件是一朵一朵的花,就看你需要向花瓶中插入哪些花了。圖5-6是項目組織結構。
圖5-6 項目組織結構
還記得前面項目運行時出現的閃屏畫面吧,該畫面就是由splash.bmp文件指定的。閃屏圖片必須是bmp格式的圖片,一旦刪除該文件,或者更改文件名稱,將不會出現閃屏畫面。另外,圖5-6中的introContent.xml、content文件夾用于定制程序啟動主界面中的Welcome歡迎畫面(見圖5-4)??梢园凑兆约旱男枰薷臍g迎畫面,關于閃屏畫面的制作將在第7章詳細說明。下面認識一下項目組織結構的各個部分。
1.src
src文件夾存放了項目的源程序,那么編譯后的class文件在哪兒?項目組織結構中并沒有列出,實際保存在bin文件夾下?;叵胍幌?,在本章一開始就設置了系統默認文件輸出組織方式(見圖5-1)。今后操作過程中應該知道在哪里找源代碼,在哪里找class文件。
2.JRE System Library
該文件夾存放系統類庫文件。Eclipse已經自動幫你導入了相關類庫,你可以展開看看項目需要哪些類庫。
3.Plug-in Dependences
該文件夾存放插件依賴類庫文件。可以展開看看當前項目需要哪些插件才能正常運行。不過,要更為直觀地查看插件依賴,請雙擊build.properties文件,在打開的Overview概覽視圖中再單擊Dependencies頁,如圖5-7所示??梢钥吹浆F在的項目需要org.eclipse.ui.intro、org.eclipse.core.runtime、org.eclipse.ui這三個核心插件。這三個插件實際上還需要依賴其他插件,怎么查看依賴關系?單擊“Dependency Analysis”插件依賴性分析,再單擊“Show the plug-in dependency hierarchy”,如圖5-8,Eclipse會給出非常詳細的插件依賴關系說明。
圖5-7 插件依賴項 圖5-8 插件依賴關系明細
4.MANIFEST.MF
MANIFEST.MF文件對當前插件(項目)進行描述,并可定義與其他插件的關系,也就是插件的原數據。該文件一般不需要修改。雙擊該文件可以查看具體情況,類似于圖5-9中所示。
圖5-9 MANIFEST.MF
在MANIFEST.MF中定義了版本、插件的ID號、插件的依賴項(Require-Bundle)等等。singleton為true表示該插件項目只能有唯一版本,該參數是為了解決同一名稱插件的多版本并存問題。
Eclipse-LazyStart項比較有意思。Eclipse-LazyStart用于指定當前插件的啟動方式,具體說就是當插件中的類或者資源被訪問時,該插件是否自動啟動。Eclipse-LazyStart允許Eclipse以一種“惰激活”(懶加載)的方式啟動插件,即插件被訪問時才啟動,不訪問不啟動。這豈不很妙,RCP應用程序就可以在啟動時只需要加載盡可能少的必需插件。因此,設置為true可以提升啟動速度。
5.build.properties
build.properties用來配置插件的編譯信息,即定義與項目打包時(構建)相關的屬性定義??梢岳迷撐募?,將項目打包運行時所需要的部件或插件包含進來,如下所示形式:
source.. = src/
output.. = bin/
bin.includes = plugin.xml,"
META-INF/,"
.,"
content/,"
splash.bmp,"
introContent.xml
前面兩句指定項目打包時源文件和class文件的輸出文件夾,bin.includes則指定了項目打包時所包含的文件夾或者文件,例如閃屏圖片splash.bmp。通常情況下項目總是有很多修飾圖標或圖片,一般放置在項目的icons文件夾下。如果沒有該文件夾,輸出產品后在需要顯示圖標的地方就會顯示Eclipse默認的圖標(紅盒子)。解決方法當然很簡單,可以在build.properties最末尾加入“icons/”。如果是在中間加入,則應該是“icons/,"”形式。
6.plugin.xml
前文中已經簡單提到插件是通過擴展點(Extension point)來定義的。擴展點是插件提供服務的入口,有點類似于Java 中的接口。例如賓館服務員張三(插件)為顧客李四(插件)提供服務,張三定義好了一個服務契約擴展點,這樣一來李四通過擴展點就知道如何獲取服務、可以有哪些服務了。Eclipse采用了完全開放的擴展點機制,開發人員可以在任何覺得可能被擴展的地方定義擴展點,以方便其他人擴展系統的功能,例如添加工具欄、菜單等等。這樣一來,系統的開放程度主要取決于擴展點多少了。擴展點信息保存在plugin.xml文件中。
下面是一個菜單的擴展點定義。
<extension
point="org.eclipse.ui.actionSets">
<actionSet
id="cn.edu.jfcs.actionSet"
label="Sample Action Set"
visible="true">
<menu
id="sampleMenu"
label="擴展點測試">
<separator name="sampleGroup"/>
</menu>
<action
class="cn.edu.jfcs.actions.SampleAction"
icon="icons/sample.gif"
id="cn.edu.jfcs.actions.SampleAction"
label="單擊試試"
menubarPath="sampleMenu/sampleGroup"
toolbarPath="sampleGroup"/>
</actionSet>
</extension>
l org.eclipse.ui.actionSets是工具欄或者菜單的操作集擴展點。
l <actionSet>項定義了操作集的標識、名稱和可視性。
l <menu>項定義了菜單的標識、名稱。
l <action>項定義了下拉菜單項的類名(沒有編寫,選中時執行的任務)、圖標、標識、名稱、路徑等等。
將上述代碼復制粘貼到plugin.xml文件</plugin>的前面,保存并運行看看!現在多了一個【擴展點測試】菜單,單擊其下的子菜單項【單擊試試】,將彈出一個“Information”對話框,提示“The chosen operation is not currently available.”(選擇的操作當前不可用)。這是因為cn.edu.jfcs.actions.SampleAction還沒有編寫。試驗完畢后,記得將該擴展點從plugin.xml文件中刪除。當然Eclipse的擴展點較多,讀者可以參考Eclipse自帶的幫助或者其他書籍進行學習。
5.1.3 RCP基本框架
一個基本的RCP應用程序已經搭建起來,盡管還非常稚嫩,卻已經初具雛形。探究一下RCP的基本框架對于理解RCP大有好處。從前面圖5-6可以看出,Eclipse已經自動生成了Application.java、ApplicationActionBarAdvisor.java、ApplicationWorkbenchAdvisor.java、ApplicationWorkbench- WindowAdvisor.java、Perspective.java這5個類文件。有必要對這5個文件進行分析,以便更深刻地理解RCP的基本框架。在分析之前,先來簡單理解一下幾個基本概念。
1.基本概念
(1)Display
應用程序一般只需要一個Display對象,該對象實際上是一個SWT對象,代表了底層圖形系統的實現。Display的主要任務是事件處理,它負責從操作系統的事件隊列中讀取事件,傳遞給RCP的事件監聽器以便完成具體的任務。需要注意的是,Display對象不代表應用程序窗口的任何可視控件,在應用程序主窗口打開之前,Display是不可獲得的。應用程序主窗口打開之后,才可以通過一個被稱作Shell的對象獲得。Display對象的獲得方法如下。
Display display = new Display();
或者:Display display=Display.getCurrent();
(2)Shell
每一個窗口都有一個Shell對象。Shell對象代表了與用戶交互的窗口框架,并處理與窗口關聯的諸如移動、改變大小等常見行為。Shell對象的獲得方法:
Display display=Display.getCurrent();
Shell shell = new Shell(display);
或者:Shell shell=Display.getCurrent().getActiveShell();
(3)Workbench
Workbench是工作臺,通俗地說就是代表用戶界面的UI元素。工作臺上有各種窗口、圖標、按鈕和控件,用戶可以在工作臺上做各種操作。獲得工作臺對象的方法:
IWorkbench wb=PlatformUI.getWorkbench();
工作臺對象有兩個方法也許很有用:
l wb.restart(),關閉應用程序并立即重新啟動。
l wb.close(),正常關閉應用程序,等同于ActionFactory.QUIT_ACTION。
(4)Advisor
Advisor是建議者,用戶主界面寬度、高度、圖標、菜單、工具欄、顏色、操作等等配置方案需要Advisor來提出“建議”。Eclipse提供了3種類型的Advisor:
l WorkbenchAdvisor。應用程序級別,Eclipse3.0開始引入的全新類。每一個應用程序只有一個Workbench,WorkbenchAdvisor負責該工作臺生命周期的管理,例如啟動、關閉工作。WorkbenchAdvisor也負責該Workbench的異常處理,并負責向Workbench提供一些重要參數,例如可以指定該Workbench的初始透視圖。
l WorkbenchWindowAdvisor。窗口級別。每一個窗口都有一個WorkbenchWindow- Advisor 實例。WorkbenchWindowAdvisor 負責具體窗口生命周期的管理,例如狀態欄、工具欄、菜單、窗口標題、窗口大小和各種控件等等,也可以處理窗口的各種事件例程。
l ActionBarAdvisor。窗口級別。每一個窗口都有一個ActionBarAdvisor實例。ActionBarAdvisor負責管理窗口的菜單欄、狀態欄、工具欄的外觀和行為。
(5)View和Editor
在Eclipse RCP應用程序中,用戶主要通過視圖(View)和編輯器(Editor)來與程序交互。視圖是可以浮動的工作窗口,負責顯示數據在某個層面的狀態信息。編輯器也是一種工作窗口,提供對數據進行各種操作的交互能力。至于是使用視圖還是使用編輯器,沒有很嚴格的區分,取決于開發者和用戶需求的考慮,例如,應用程序的界面可以毫無障礙地全部使用視圖來實現。經費測算系統只有公共參數設置功能模塊使用編輯器實現,其他大部分界面均采用視圖來實現。
視圖擴展自ViewPart抽象類。開發者通常需要在createPartControl()方法中編寫代碼,以便構建視圖的界面元素。下面是一個沒有任何處理代碼的簡單視圖。
package cn.edu.jfcs.ui;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
public class TeachUnitName extends ViewPart {
public TeachUnitName() {
// TODO Auto-generated constructor stub
}
public void createPartControl(Composite parent) {
// TODO Auto-generated method stub
}
public void setFocus() {
// TODO Auto-generated method stub
}
}
(6)Perspective
Perspective與視圖、編輯器之間的關系類似于書包和書、筆的關系。書包里面可以放各種書和筆,書包是Perspective,而書和筆則類似于視圖和編輯器。Perspective被稱之為透視圖,RCP應用程序是通過透視圖對窗口內容進行安排和布局的,應用程序都有一個默認的透視圖,每個工作臺窗口則可以包含一個或多個透視圖,同時用戶可向透視圖中添加其他UI界面元素。默認透視圖被設置為固定的,不能移動,而且沒有標題欄。例如運行經費測算系統后,單擊【Help】→【Welcome】,將在默認透視圖中打開Welcome歡迎界面。關閉該歡迎界面,就會顯示一個沒有標題欄、只有最小化最大化按鈕的空界面,該界面即為默認的透視圖。
透視圖需要實現IPerspectiveFactory接口。IPerspectiveFactory可以說是產生初始頁面布局和可視性透視圖的工廠。在Eclipse中,工作臺打開的任何新頁面都需要一個透視圖定義其初始布局。具體說來,就是需要向透視圖工廠傳遞一個IPageLayout對象,通過該對象安排視圖或者編輯器的初始布局。默認情況下,初始布局包含了一個可視的編輯區。當然,該編輯區也可以關閉。
2.類文件分析
(1)Application.java
對于普通Java應用程序來說,總是有一個main()方法,應用程序總是從main()開始運行。Application類似于Java應用程序的main(),即RCP應用程序運行開始于Application,Application是RCP應用程序的入口。Application實現了IPlatformRunnable接口,在RCP啟動的時候將會執行該接口的run()方法。從plugin.xml可以獲知,Application實際上是Eclipse org.eclipse.core.runtime.applications運行時擴展點的一個入口。Application主要代碼如下:
cn.edu.jfcs.app/Application.java
import …
public class Application implements IPlatformRunnable {
public Object run(Object args) throws Exception {
Display display = PlatformUI.createDisplay();
try {
int returnCode = PlatformUI.createAndRunWorkbench(display,
new ApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART) {
return IPlatformRunnable.EXIT_RESTART;
}
return IPlatformRunnable.EXIT_OK;
} finally {
display.dispose();
}
}
}
可以把Application當作RCP應用程序的控制者,它負責應用程序的啟動、停止。Application首先創建一個Display對象,然后調用PlatformUI.createAndRunWorkbench()方法啟動工作臺,這將打開應用程序主窗口,并處于持續打開狀態。應用程序開始處理用戶的鼠標單擊、鼠標移動、按鍵等各種事件,一直到用戶關閉程序退出,這就是所謂的事件循環。當然,在關閉之前,必須銷毀Display對象以釋放資源(display.dispose())。
從上面的分析可以得到這樣一個信息:應用程序主窗口只有在語句“int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());”調用之后才會打開并可視化。開發人員可以利用這一點做做文章,例如在其前面加入啟動登錄窗口、啟動Derby數據庫服務器、初始化處理等等工作,代碼類似于下面的形式。
……
//啟動Derby數據庫服務器
//打開登錄界面
int returnCode = PlatformUI.createAndRunWorkbench(display,
new ApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART) {
return IPlatformRunnable.EXIT_RESTART;
}
……
第6章中的實現用戶登錄處理,就是基于這種處理思路。注意到PlatformUI.createAndRun- Workbench()方法中,除了display對象,還向其傳遞了另外一個對象:new Application- WorkbenchAdvisor(),那么ApplicationWorkbenchAdvisor又是做什么的?
(2)ApplicationWorkbenchAdvisor.java
ApplicationWorkbenchAdvisor類負責應用程序生命周期管理,繼承自WorkbenchAdvisor類。開發人員可以在該類中實現程序啟動或者關閉時的某種處理。該類的具體實現只是給用戶一個初始的視圖界面而已,還需要配合WorkbenchWindowAdvisor、ActionBarAdvisor才能構成一個較為完整的用戶界面。ApplicationWorkbenchAdvisor類主要有5個重要的方法,按照執行的先后順序排列如表5-1所示。
表5-1 ApplicationWorkbenchAdvisor主要方法
方 法 名 |
方 法 說 明 |
initialize |
最先調用。在窗口打開之前調用,可以用來處理初始化配置工作 |
preStartup |
initialize之后、第一個窗口打開之前調用,可以用來處理臨時或者可選處理工作 |
postStartup |
第一個窗口打開之后但啟動事件循環之前調用,可以用來進行那些需要自動處理的工作,例如彈出一個提示窗口 |
preShutdown |
事件循環結束之后但窗口關閉之前調用,可以用來進行保存數據、關閉數據庫服務器等處理工作 |
postShutdown |
窗口關閉之后調用,可以用來進行保存應用程序狀態、清除initialize創建的對象等處理工作 |
ApplicationWorkbenchAdvisor.java主要代碼如下。
cn.edu.jfcs.app/ ApplicationWorkbenchAdvisor.java
import …
public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
private static final String PERSPECTIVE_ID = "cn.edu.jfcs.perspective";
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
IWorkbenchWindowConfigurer configurer) {
return new ApplicationWorkbenchWindowAdvisor(configurer);
}
public void initialize(IWorkbenchConfigurer configurer) {
super.initialize(configurer);
configurer.setSaveAndRestore(true);
}
public String getInitialWindowPerspectiveId() {
return PERSPECTIVE_ID;
}
}
上述程序主要做了兩件事情:一是初始化需要在主界面顯示的透視圖(Perspective),創建并返回ApplicationWorkbenchWindowAdvisor對象。二是初始化方法中代碼configurer.setSaveAndRestore(true)用于設置應用程序每次退出時保存當前窗口狀態,并在下次啟動時應用,這對應用程序性能稍有影響,建議修改為false不保存。getInitialWindowPerspectiveId()方法打開默認的透視圖cn.edu.jfcs.perspective。
|
如果在初始化initialize事件中編寫大量處理代碼,會引起應用程序啟動時主窗口的延遲顯示,給用戶以系統速度較慢的感覺。因此,應該盡量避免。 |
(3)ApplicationWorkbenchWindowAdvisor.java
ApplicationWorkbenchWindowAdvisor類負責應用程序窗口生命周期的管理,該類擴展自WorkbenchWindowAdvisor。每一個應用程序都需要一個WorkbenchWindowAdvisor來控制窗口界面的UI元素。開發人員可以控制窗口創建時的大小、標題、位置等等,也可以添加創建、打開、還原或關閉工作臺窗口時調用的方法。ApplicationWorkbenchWindowAdvisor主要方法如表5-2所示。
表5-2 ApplicationWorkbenchWindowAdvisor主要方法
方 法 名 |
方 法 說 明 |
preWindowOpen |
窗口控件創建之前調用,可以在該方法中設置窗口的初始大小、狀態欄、工具欄等的可視性 |
postWindowRestore |
當窗口根據上一次的保存狀態恢復創建之后調用,可以用來調整調整窗口恢復狀態 |
postWindowCreate |
窗口創建之后調用,可以用于調整窗口 |
postWindowOpen |
窗口已經打開之后調用,可以用來注冊窗口監聽,例如在此方法中實現系統托盤 |
下面我們來看看Eclipse自動生成的ApplicationWorkbenchWindowAdvisor.java主要代碼如下:
cn.edu.jfcs.app/ ApplicationWorkbenchWindowAdvisor.java
import …
public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
super(configurer);
}
public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
return new ApplicationActionBarAdvisor(configurer);
}
public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
configurer.setInitialSize(new Point(700, 550)); //定義窗口初始化大小
configurer.setShowCoolBar(false); //不顯示工具欄
configurer.setShowStatusLine(false); //不顯示狀態欄
configurer.setTitle("jfcs"); //窗口標題為jfcs
}
}
該類創建了一個ApplicationActionBarAdvisor對象,并通過preWindowOpen()方法方法配置窗口。在preWindowOpen()方法中,首先生成了configurer對象,通過該對象配置窗口的大小、工具欄、狀態欄、標題等可視化元素,也就是說控制窗口的外觀。默認狀態下工具欄和狀態欄都是隱藏的。IWorkbenchWindowConfigurer是一個接口類,該接口類提供了很多set/get方法以便用戶訪問存取工作臺窗口的配置。實際上,大家可能也注意到了,每種類型的Advisor都有一個對應的configurer。ApplicationWorkbenchAdvisor中的IWorkbenchConfigurer、ApplicationWorkbenchWindowAdvisor中的IWorkbenchWindowConfigurer、后面Application- ActionBarAdvisor中的IActionBarConfigurer,configurer是與工作臺、窗口、菜單、工具欄和狀態欄打交道的一座方便的橋梁。
(4)ApplicationActionBarAdvisor.java
ApplicationActionBarAdvisor.java類負責定義窗口的行為,該類擴展自ActionBarAdvisor。具體地說,該類用于構建菜單欄、工具欄和狀態行。ActionBarAdvisor自然是負責菜單欄、工具欄和狀態行的創建和注冊。ApplicationActionBarAdvisor主要方法如表5-3所示。
表5-3 ApplicationActionBarAdvisor主要方法
方 法 名 |
方 法 說 明 |
void makeActions(IWorkbenchWindow window) |
注冊菜單或者工具欄的動作 |
void fillMenuBar(IMenuManager menuBar) |
添加菜單欄 |
void fillCoolBar(ICoolBarManager coolBar) |
添加工具欄 |
void fillStatusLine(IStatusLineManager statusLine) |
添加狀態欄 |
ApplicationActionBarAdvisor.java主要代碼如下。
cn.edu.jfcs.app/ ApplicationActionBarAdvisor.java
import …
public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
private IWorkbenchAction introAction;
public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
super(configurer);
}
protected void makeActions(IWorkbenchWindow window) {
//利用ActionFactory動作工廠創建introAction
introAction = ActionFactory.INTRO.create(window);
register(introAction);
}
protected void fillMenuBar(IMenuManager menuBar) {
MenuManager helpMenu = new MenuManager("&Help",
IWorkbenchActionConstants.M_HELP);
menuBar.add(helpMenu);
helpMenu.add(introAction);
}
}
該程序創建了一個幫助菜單欄,其子菜單所執行的動作采用Eclipse內置的ActionFactory.INTRO,執行該動作將顯示Welcome歡迎畫面。
(5)Perspective.java
Perspective類主要負責界面布局的安排。Perspective.java代碼如下。
cn.edu.jfcs.app/ Perspective.java
import …
public class Perspective implements IPerspectiveFactory {
public void createInitialLayout(IPageLayout layout) {
String editorArea = layout.getEditorArea(); //獲得布局的編輯區
layout.setEditorAreaVisible(false); //隱藏編輯區
layout.setFixed(true); //固定布局
// 此處加入各種視圖
}
}
createInitialLayout()方法通常用于創建初始的界面布局,當前是空實現,所以打開經費測算系統并關閉歡迎畫面后,界面會出現空白,后面將加入主界面視圖。
5.1.4 定制應用程序窗口屬性
向導生成的應用程序主界面并不能滿足要求,存在很多問題,例如,主界面運行時沒有自動居中,主界面大小沒有固定,主窗口標題欄文字應該是“高校經費測算系統”。再看看圖5-3、圖5-4的標題欄有區別沒有?當然有,圖5-3所示界面的標題欄是很漂亮的弧線形,而圖5-4所示界面的標題欄則不是。如此等等,需要重新設置。
1.閃屏畫面
應用程序主界面顯示之前往往需要做一些初始化處理工作,就是啟動時間可能稍微長一些,如果沒有任何提示,用戶可能會感到困惑,閃屏畫面能夠較好地解決這個問題。準備一幅24bit色BMP格式的圖片,注意圖片大小不要超過500mm×300mm。將該圖片復制到項目文件夾中替換掉原來的splash.bmp文件即可。
2.不保存窗口狀態
將ApplicationWorkbenchAdvisor.java的initialize()方法中的語句:configurer.setSaveAndRestore(true);
修改為:configurer.setSaveAndRestore(false);
前文說過,設置為true,應用程序每次退出時將保存窗口狀態,此處并不需要且對性能有輕微影響,所以設置為false。
3.定制窗口式樣
再來定制主窗口。前面已經介紹過,在ApplicationWorkbenchWindowAdvisor.java的preWindowOpen()方法中定制窗口式樣,現在修改如下。
cn.edu.jfcs.app/ ApplicationWorkbenchWindowAdvisor.java
public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
//窗口設定為800x600
configurer.setInitialSize(new Point(800, 600));
//暫時不顯示工具欄
configurer.setShowCoolBar(false);
//顯示狀態欄
configurer.setShowStatusLine(true);
//窗口只顯示最小化、關閉按鈕
configurer.setShellStyle(SWT.MIN | SWT.CLOSE);
//設置窗口標題
configurer.setTitle("高校經費測算系統");
}
執行上步操作后,我們會發現configurer.setShellStyle(SWT.MIN | SWT.CLOSE)這句代碼的旁邊出現一個帶紅色叉叉的小燈泡,這意味著該行代碼有問題,這是因為使用了SWT.MIN常量而又沒有導入相應類。解決方法很簡單,只需鼠標單擊小燈泡,根據彈出的提示導入包import org.eclipse.swt.SWT即可,這也是Eclipse很貼心的小功能?,F在運行看看,程序主界面已經有了較大變化。
程序中最后一句代碼中的“高校經費測算系統”是一個自定義常量。一個系統中有很多類似的自定義常量,例如圖片的名稱、視圖的名稱等等,而這些常量可能不止一個地方需要使用到。一個很好的方法是創建一個接口文件,將全部常量的定義放置到該接口文件中,這樣可以統一管理,而且維護方便。如果要修改某個常量的值,只需要到接口文件中修改就可以了。下面來實現該處理,新建一個包cn.edu.jfcs.sys,在該包下新建接口類IAppConstants.java,代碼類似于以下形式。
package cn.edu.jfcs.sys;
public interface IAppConstants {
public static final String APPLICATION_TITLE="高校經費測算系統";
}
現在只需要將ApplicationWorkbenchWindowAdvisor.java中preWindowOpen()方法的configurer.setTitle("高校經費測算系統")修改為configurer.setTitle(IAppConstants.APPLICATION_ TITLE)即可。記得導入cn.edu.jfcs.sys.IAppConstants類。
|
以后還會不斷往該接口文件中添加常量定義。為了避免不必要的麻煩,建議讀者在實際操作時先將本書附帶源代碼的IAppConstants.java類直接復制到自己的項目中。 |
4.窗口自動居中
窗口居中需要手工編程實現,編寫之前先得想想代碼放在哪兒?還是放在preWindowOpen()方法中嗎?當然不行,preWindowOpen()是配置窗口的構成元素,即形成窗口本身的構成部件,而居中則是定義窗口的位置,顯然不屬于窗口構成元素。postWindowOpen()可以勝任此項工作,因為postWindowOpen()主要用來處理那些需要一個現成窗口才能進行的事件處理。
在代碼編輯視圖中單擊鼠標右鍵,在彈出的快捷菜單中選擇【Source】→【Override/ Implement Methods…】命令,彈出“Override/Implement Methods”對話框,勾選postWindowOpen()方法,默認將在光標所在處插入postWindowOpen()方法。這又是Eclipse的一個很貼心的功能,希望讀者熟練使用。改寫該方法的代碼如下:
cn.edu.jfcs.app/ ApplicationWorkbenchWindowAdvisor.java
public void postWindowOpen() {
//設置窗口自動居中
Shell shell = getWindowConfigurer().getWindow().getShell();
Rectangle screenSize = Display.getDefault().getClientArea();
Rectangle frameSize = shell.getBounds();
shell.setLocation((screenSize.width - frameSize.width) / 2,(
screenSize.height - frameSize.height) / 2);
}
該方法通過默認Display對象來設置屏幕寬度和高度,通過Shell對象獲得當前窗口的寬度和高度,兩者分別相減后再除以2,計算得到窗口左上角的(x,y)坐標。不要忘了導入相關的類,再看看運行后窗口是否自動居中。
5.設置視圖標題欄的弧線形外觀
大家肯定都喜歡圖5-3所示界面中弧線形的標題欄,這種風格的標題欄涉及到工作臺UI屬性(org.eclipse.ui Preference):SHOW_TRADITIONAL_STYLE_TABS??梢酝ㄟ^三種方法進行設置。
(1)硬編碼實現
硬編碼實現是指通過直接編寫代碼實現。打開ApplicationWorkbenchAdvisor.java文件,修改initialize()方法代碼如下:
cn.edu.jfcs.app/ ApplicationWorkbenchAdvisor.java
public void initialize(IWorkbenchConfigurer configurer) {
super.initialize(configurer);
configurer.setSaveAndRestore(false);
PlatformUI.getPreferenceStore().setValue(IWorkbenchPreferenceConstants.
SHOW_TRADITIONAL_STYLE_TABS, false);
}
相關的屬性很多,具體可以查看IWorkbenchPreferenceConstants接口文件。方法是,按住【Ctrl】鍵,將鼠標移動到IWorkbenchPreferenceConstants上面,IWorkbenchPreferenceConstants下面會出現下劃線,單擊鼠標左鍵即可。對于Eclipse的其他方法也是如此操作。這里先簡單介紹幾個常用屬性。
表5-4 IWorkbenchPreferenceConstants常見屬性
屬 性 名 |
屬 性 說 明 |
EDITOR_MINIMUM_CHARACTERS |
但很多編輯器重疊時,設置編輯器標題文字的最短長度。默認為8個字符 |
SHOW_PROGRESS_ON_STARTUP |
設置啟動時是否顯示進度條。默認值false |
DOCK_PERSPECTIVE_BAR |
設置透視圖標題欄停泊位置。默認值為TOP_RIGHT,還可以設置為TOP_LEFT、LEFT |
SHOW_TEXT_ON_PERSPECTIVE_BAR |
設置透視圖是否顯示標題文本。默認值為true |
SHOW_INTRO |
啟動時是否顯示歡迎畫面。默認值為true |
|
可能有些人喜歡每次啟動時顯示歡迎畫面,則可以在initialize()方法中加入: PlatformUI.getPreferenceStore().setValue(IWorkbenchPreferenceConstants.SHOW_INTRO, true); |
(2)修改產品默認配置文件
可以創建一個初始化配置文件,使用默認的配置文件名plugin_customization.ini。在項目名稱上單擊鼠標右鍵,選擇【New】→【File】,在File name后輸入plugin_customization.ini,單擊【Finish】按鈕,輸入以下內容。
#設置視圖標題欄的弧線形外觀
org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false
#編輯器標題欄提示文字最短長度
org.eclipse.ui/ EDITOR_MINIMUM_CHARACTERS =12
(3)自定義配置文件
如果你不喜歡默認的配置文件,完全可以更改配置文件名(本書采用這種方法),具體步驟如下。
① 雙擊pludin.xml文件,再單擊“Extensions”頁。
② 展開org.eclipse.core.runtime.products,在jfcs(Product)上單擊鼠標右鍵,選擇【New】→【property】。
③ 在Extension Element Details下的name后的文本框中輸入屬性名preferenceCustomization
(屬性名不能更改),value后的文本框中輸入AppPref.ini(可任意命名),具體如圖5-10所示。若要查看org.eclipse.core.runtime.products有哪些可供配置的屬性,則只需要單擊org.eclipse.core.runtime.products名,然后再單擊右邊的Open extension point description,Eclipse將打開關于Products擴展點的屬性描述,如圖5-11所示。注意到該屬性默認的文件正是前面所說的plugin_customization.ini。
圖5-10 添加屬性設置視圖
圖5-11 org.eclipse.core.runtime.products擴展點描述
④ 在項目名稱上單擊鼠標右鍵,選擇【New】→【File】,在File name后輸入AppPref.ini,單擊【Finish】按鈕,輸入配置內容即可。
這里提醒一下,如果做了很多設置,而運行時似乎沒有生效,這是由于Eclipse緩存了舊配置信息。解決方法:選擇系統菜單的【Run】→【Run…】,彈出“Run”對話框,先單擊“Eclipse Application”,再單擊“jfcs”,勾選“Clean workspace data before launching”,不要勾選“Ask for confirmation before cleaning”。這樣可以保證每次運行都是最新結果,設置畫面如圖5-12所示。
圖5-12 運行設置對話框
|
SHOW_INTRO比較特別。如果使用ini配置文件的方式,無論使用默認配置文件還是自定義配置文件,產品打包發布后(不在Eclipse環境中運行)只是首次啟動時出現歡迎畫面,這是因為Eclipse在運行結束時會修改工作空間目錄中org.eclipse.ui.prefs文件的showIntro=false,所以下次啟動時將不會出現歡迎畫面。如果希望程序每次啟動時都出現歡迎畫面,需要采取硬編碼的方式! |