在Eclipse中使用SWT進(jìn)行界面設計
1. 為什么要使用SWT?
SWT是一個(gè)IBM開(kāi)發(fā)的跨平臺GUI開(kāi)發(fā)工具包。至于為什么IBM要費勁自己另起爐灶開(kāi)發(fā)一個(gè)GUI工具包,而不是使用Sun現有的由AWT, Swing, Java 2D, Java 3D等構成的Java GUI框架,那就說(shuō)來(lái)話(huà)長(cháng)了。(記得在一個(gè)BBS上讀過(guò)一個(gè)關(guān)于SWT起源的調侃類(lèi)的帖子)。
在SWT之前,Sun已經(jīng)提供了一個(gè)跨平臺GUI開(kāi)發(fā)工具包AWT (Abstract Windowing Toolkit)。雖然AWT框架也使用的是原生窗口部件(native widgets),但是它一直未能突破LCD問(wèn)題。LCD問(wèn)題導致了一些主要平臺特征的遺失。如果你不明白的話(huà)(其實(shí)我也沒(méi)明白),換句話(huà)說(shuō),如果平臺A有窗口部件(widgets)1–40,而平臺B有窗口部件(widgets)20–25,那么跨平臺的AWT框架只能提供這兩個(gè)窗口部件集的交集。
為解決這個(gè)問(wèn)題,Sun又創(chuàng )建了一個(gè)新的框架。這個(gè)框架不再使用原生窗口部件,而是使用仿真窗口部件(emulated widgets)。這個(gè)方法雖然解決了LCD問(wèn)題,并且提供了豐富的窗口部件集,但是它也帶來(lái)了新的問(wèn)題。例如,Swing應用程序的界面外觀(guān)不再和原生應用程序的外觀(guān)相似。 雖然在JVM中這些Swing應用程序已經(jīng)得到了最大程度的性能改善,但是它們還是存在著(zhù)其原生對應物所不具有的性能問(wèn)題。并且,Swing應用程序消耗太多的內存,這樣Swing不適于一些小設備,如PDA和移動(dòng)電話(huà)等。
IBM進(jìn)行了嘗試以徹底解決AWT和Swing框架帶來(lái)的上述問(wèn)題。最終,IBM創(chuàng )建了一個(gè)新的GUI庫,這就是SWT。SWT框架通過(guò)JNI來(lái)訪(fǎng)問(wèn)原生窗口部件。如果在宿主(host)平臺上無(wú)法找到一個(gè)窗口部件,SWT就會(huì )自動(dòng)地模擬它。
2. SWT應用程序的組成
一個(gè)SWT應用程序的基本組成部分為顯示界面(Display)、命令界面(Shell,使命令進(jìn)入并使運行初始化)和窗口部件(Widgets)。Display負責管理事件循環(huán)和控制UI線(xiàn)程和其他線(xiàn)程之間的通訊。Shell是應用程序中被操作系統窗口管理器管理的窗口。每個(gè)SWT應用程序至少需要一個(gè)Display和大于等于1個(gè)的Shell實(shí)例。
圖1從不同的角度展示了SWT應用程序。左側的圖是一個(gè)簡(jiǎn)化的UI對象的繼承圖。中間的圖展示了UI對象的容器結構(containment structure)。右側的圖則是創(chuàng )建后的UI外觀(guān)。
如果一個(gè)應用程序使用了多個(gè)線(xiàn)程,那么每個(gè)線(xiàn)程都使用的是Display對象分配給它自己的實(shí)例。程序員可以使用靜態(tài)方法Display.getCurent()來(lái)得到Display對象的當前活動(dòng)的實(shí)例。
Shell用于在特定的操作系統中表現窗口。Shell可以最大化、最小化或正?;?。Shell有兩種類(lèi)型。第1種是高層shell,它是Display的子窗口,同時(shí)它也是一個(gè)主窗口。第2類(lèi)是對話(huà)shell,這種shell要依賴(lài)于其他的shell窗口存在。shell窗口最終成為上述那種類(lèi)型,要看在創(chuàng )建shell時(shí)傳遞給shell構造函數的是什么風(fēng)格位(style bits)。一個(gè)shell的默認值是DialogShell。也就是說(shuō),如果不帶參數,那默認就是一個(gè)對話(huà)shell。而如果給參數賦予了一個(gè)Display對象,則該shell將是一個(gè)高層shell。
一些窗口部件的屬性必須在創(chuàng )建它們的初期就要被設置。這些窗口部件的屬性就是前面所說(shuō)的風(fēng)格位(style bits)。在SWT的類(lèi)中,風(fēng)格位被定義為常數。例如,Button button = new Button( shell, <styleBits> )??梢允褂没颍∣R)操作符“|”來(lái)設置多個(gè)風(fēng)格位。例如,如果想設置一個(gè)帶邊界的壓下按鈕,需要傳遞SWT.PUSH | SWT.BORDER作為風(fēng)格位參數。
3. 進(jìn)行SWT開(kāi)發(fā)前的環(huán)境設置
為了進(jìn)行SWT應用開(kāi)發(fā),你需要把SWT庫添加到類(lèi)路徑(classpath)上,并設置必要的環(huán)境變量。
首先,你要在ECLIPSE_HOME\eclipse\plugins\org.eclipse.swt.win32_2.1.0\ws\win32目錄下找到swt.jar庫文件。注意這里的“org.eclipse.swt.win32_2.1.0”目錄是和Eclipse的版本有關(guān)的。實(shí)在找不到你就用文件搜索功能吧。然后依次打開(kāi)下面窗口Project->Properies->JavaBuildPath->Libraries->Add Variable -> Eclipse Home ->Extend將swt.jar文件加到類(lèi)路徑中。
接著(zhù),你肯定想編譯這個(gè)SWT應用了。但是會(huì )出現下面所示的運行異常。出現這個(gè)異常的原因是swt.jar庫使用的是原生庫。你需要設置java.library.path環(huán)境變量來(lái)使用Java中的原生庫。
控制臺(Console )的輸出如下:
java.lang.UnsatisfiedLinkError: no swt-win32-2136 in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:108)
at org.eclipse.swt.internal.win32.OS.<clinit>(OS.java:46)
at org.eclipse.swt.widgets.Display.internal_new_GC(Display.java:1291)
at org.eclipse.swt.graphics.Device.init(Device.java:547)
at org.eclipse.swt.widgets.Display.init(Display.java:1316)
at org.eclipse.swt.graphics.Device.<init>(Device.java:96)
at org.eclipse.swt.widgets.Display.<init>(Display.java:291)
at org.eclipse.swt.widgets.Display.<init>(Display.java:287)
at com.swtdesigner.trytry.main(trytry.java:24)
Exception in thread "main"
按下面的步驟設置java.library.path變量:依次打開(kāi)Run-> Run...-> Java Applicaton-> "Project" ->Arguments -> VM Arguments。在“VM Arguments”中輸入
-Djava.library.path=c:\eclipse\plugins\org.eclipse.swt.win32_2.1.0\os\win32\x86
注意要輸入你自己的swt.jar所在的路徑。
小技巧:加載原生庫:
如果你需要加載自己應用程序所使用的原生庫,可以使用Runtime.getPlatform.loadLibrary("libraryname")方法。
再編譯一次你的應用程序,這次通過(guò)了吧。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。