Java的GUI發展-AWT/SWT/Swing

                                                                  從AWT到Swing,再從SWT到Swing

轉載:http://bbs.csdn.net/topics/350252577

gui
    應用程序是軟件的一種主要類型,所以java的gui庫應該是標準化並被集成到jre平臺中的。然而不同的操作系統有不同的gui風格和組件集。有一些組件在所以平臺上有相似的觀感。這些共有組件如按鈕,標籤,文本域,單選框等被稱爲標準組件。不同的gui工具集提供了不同的組件集。gui工具集總是遵循不同的原則來選擇組件類型和特徵以實現。考察一個工具集,有兩個不同的要素:組件類型和組件特徵。

一、GUI特性:組件類型和組件特徵
1、terms
    首先讓我圖解兩個數學概念:最大公約數和最小公倍數。三個集合代表不同的操作系統。相交的部分是最大公約數,合併的部分是最小公倍數。
現在讓我們來考察java gui工具集awt,swt和swing的區別。

2、awt
    awt組件集遵循最大公約數原則,即awt只擁有所有平臺上都存在的組件的公有集合。所以你在awt中無法獲取如表或樹等高級組件,因爲它們在某些平臺上不支持。awt的組件特徵同樣遵循這一原則。它只提高平臺上公有的特徵。例如awt按鈕不能附着圖片,因爲在motif平臺上,按鈕是不支持圖片的。
    由於它低劣的組件集和特徵,awt無法吸引開發者。它是sun不推薦使用的,只是爲了確保向下兼容和支持swing。

3、swt
    swt 最初的目標之一是爲了提供比awt更爲豐富的組件集。它遵循最小公倍數原則以提供一個各個平臺上包含的組件的並集。思路是如果一個組件在某個平臺上包含,那麼swt就會包裝它並用java代碼和jni來調用它。如果一個組件在某一平臺上不存在,它就會用繼承並繪製composite的方式來模擬組件。一個 swt composite類似於awt的canvas。以這種方式,swt提供了較awt更爲豐富的組件集。值得指出的是swt的jni封裝不同於awt,它的模擬也不同於swing。
    在組件特徵方面,swt類似於awt。它遵循最小公倍數原則。在早期的swt版本中,swt按鈕因爲和awt同樣的原因不支持附着圖片。在之後的版本中,許多缺失的特徵採用模擬的方式補全。但仍有許多特徵無法採用純粹的模擬實現。swt將組件的控制交給本地操作系統。它難以擴展。只有例如圖形裝飾等特徵可以藉助模擬繪製來自定義實現。所以嚴格意義上將,swt組件的組件集和特徵因其難於擴展而不如swing來得豐富。

4、swing
    swing 是三者中最強大和靈活的。
    在組件類型上,它遵循最大公約數原則。由於swing可以控制自身gui系統的全部並有很好的可擴展和靈活性,它幾乎可以創建所有你想象得到的組件。唯一的限制是它的awt容器。在swing中你還不能跨平臺地實現真正的透明化和不規則矩形窗口,因爲swing依賴於awt頂層容器例如applet, window, frame and dialog等。除此之外,swing幾乎實現了所有平臺上的標準組件。
    在組件特徵上,swing遵循最小公倍數原則。它擁有所有平臺上可提供的組件特徵。不僅如此,你還可以繼承已有的swing組件並添加新的特性。
上面比較主要是在api級別上的。讓我們將比較的焦點轉移到實現細節上。awt,swt和swing的區別是swing是純java實現,而swt和awt 是java和jni的混合。當然,它們的目標都是相同的,提供一個跨平臺的apis。然而爲了達到這一點,swt和awt不得不犧牲一些組件和特性以提供一個通用的apis。

二、實現細節方面
1、awt
    一個awt組件通常是一個包含了對等體接口類型引用的組件類。這個引用指向本地對等體實現。舉java.awt.label爲例,它的對等體接口是 labelpeer。labelpeer是平臺無關的。在不同平臺上,awt提供不同的對等體類來實現labelpeer。在windows上,對等體類是wlabelpeer,它調用jni來實現label的功能。這些jni方法用c或c++編寫。它們關聯一個本地的label,真正的行爲都在這裏發生。作爲整體,awt組件由awt組件類和awt對等體提供了一個全局公用的api給應用程序使用。一個組件類和它的對等體接口是平臺無關的。底層的對等體類和jni代碼是平臺相關的。
 
2、swt
    swt也使用jni的方法論來實現。但細節不同於awt。swt的擁護者聽到人們拿swt和awt相提並論可是會很生氣的,steve northover,swt之父,就曾爲此抱怨過。
    沒錯,它們是不同的。讓我們深究swt的代碼。在swt中,各個平臺上唯一相同的部分是組件的接口,是類和方法的定義簽名。所有的底層代碼都是平臺差異的。 swt爲每個平臺提供了os類。這個類用jni封裝了許多本地apis。swt組件類通過把這些jni方法黏合在一起提供一個有意義的功能。
例如,在windows上,文本域的選擇是由一個系統調用處理的。這個系統調用在windows的os類中作爲一個本地方法實現。所以在windows平臺的text的setselection方法中只用到了一個jni調用。然而,在motif上,文本域的選擇包含兩個本地調用。swt就在motif的os類中實現了兩個調用。所以在motif上組件類需要作兩次調用來實現文本的選擇。
    現在你應該能看出swt和awt的最大不同了,它們使用了不同的對等體編程方式來消除平臺差異。swt用java代碼或有jni實現的java對等體來黏合系統調用。而awt把代碼包含在對等體中,使情況複雜化了,我個人覺得swt的方法更加明智。

3、swing
    到了swing這裏,一切就變得清晰和直接了。除了頂層容器,swing的實現不依賴於具體平臺。它掌管了所有的控制和資源。swing所需要的是事件輸入來驅動系統,以及承接自頂層awt容器的圖形處理,字體和顏色。普通的swing組件可以看作是awt容器的一塊邏輯區域。它們並沒有註冊對等體。所有添加到同一頂層容器的swing組件共享它的awt對等體以獲取系統資源,如字體,圖形處理等。swing將組件自己的數據結構存儲在jvm的空間中。它完全由自己管理畫圖處理,事件分發和組件佈局。
 
三、對比分析
1、本地組件的引用方式
    由於awt和swt都持有對本地組件的引用,它們必須以正確的方式釋放這些引用以避免內存泄露和jvm崩潰。awt將絕大多數資源管理任務交給系統,將開發者從單調乏味的資源管理中解救出來。然而這使得awt的實現複雜化了。一旦它實現了,開發者很少有機會犯錯誤並使他們的程序崩潰。
    swt 用的是另一種方法。大體上,swt讓開發者自己來管理資源。它的一條著名的規則是:誰創建,誰釋放。因此開發者必須謹慎地顯式調用dispose方法釋放每一個由他創建的組件和資源。這簡化了swt的實現模型,但把開發者擺在了因錯誤編碼而易於造成程序崩潰這一風險之上。

2、模擬方式的區別
    swt和swing在它們的實現上都使用了模擬。swt只模擬平臺上缺失的組件。區別是swt的模擬更像是awt的canvas實現的模擬。swt的 composite類有它自己在操作系統中相應的對等體。它從自己的對等體中獲得所有它所需要的資源如圖形處理的對象,字體和顏色等。它直接從操作系統獲取所有的事件並進行處理。然而,swing組件在操作系統中沒有相應的對等體。它只是一塊頂層容器中的邏輯區域,實際上它從頂層容器的對等體中借用資源。 swing的事件並不是底層系統產生的事件。它們實際是由頂層容器處理awt事件所產生的僞事件。我們會在稍後的事件部分中詳細介紹它。

3、圖形層結構
    另一個不同之處是swing組件的z-order系統是來自於awt組件的。如上所述,swing組件與頂層awt容器共享一個對等體。因此,swing組件也和頂層容器有相同的z-order。swt和awt組件都有不同於頂層容器的z-order,通常是高於頂層容器。故而如果awt組件和swing組件混合在一起的話,swing組件將可能被awt組件遮住。當操作系統開始更新ui的時候,頂層容器和swing組件總是先於awt組件繪製。當它們完成繪製,awt組件會覆蓋swing可能繪製過的地方。因此不提倡swing和awt組件的混用。如果有一個浮動的swing組件如菜單,awt組件很可能遮蓋菜單。以上是awt,swt和swing的區別的介紹。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章