AWT,SWT&SWING

來源:互聯網
上載者:User

Overview概述
     Java GUI 工具包一直是一個倍受爭議的話題。同樣的爭論也發生在其他程式設計語言如Smalltalk。實際上每個平台無關的語言都存在著這樣的爭論。Java作為當前最受廣泛使用的程式設計語言而尤為突出。

    這場爭論在支援類比組件(如widgets和control,在下文中也稱之為仿造組件)和支援本機群組件(在下文中也稱之為原生組件)的人們之間展開,於是Java開發人員形成了兩個不同的陣營,提倡使用類比組件的Swing,和提倡使用原生組件的SWT。

曆史
   Internet上有許多圍繞這一爭論的故事。你可能已經聽說過它們中的大多數了,其中之一有助於讓你理清頭緒,讓我們就從這裡開始,Amy Fowler是Swing陣營的一個倡導者。

 
回到上個世紀90年代,曾幾何時有3家龐大的Smalltalk公司——IBM、Parc-Place和 Digitalk。在90年代初期3家公司的市場份額大致相等,生活是美好的。Parc-Place採用仿視窗組件(emulated widgets)的設計(即Swing的設計),IBM和Digitalk則採用原生視窗組件(native widgets)。後來IBM壓倒了另外兩家,因此他們打算合并成一家,假設叫做Parc-Place Digitalk。隨後當他們試圖將他們的產品融合到一個叫做Jigsaw的計劃中時爆發了一場大戰,計劃由於政治原因失敗了(開發人員實際上已經能讓它運轉起來),就因為原生和仿造兩派的死戰。

     Amy贏得了精神上的勝利,不過IBM贏得了他們所有的生意,因為這兩家公司在一整年裡除了吵架什麼都沒做。當塵埃落定之後PPD(Parc-Place Digitalk當時已改名為Objectshare,跟Windscale改名為Sellafield的原因相同——讓人們淡忘之前發生的災難)的股票價格從60美元掉到了低於1美元1股。他們因為偽報收入被NASDAQ摘牌,從此消失。

    當時,AWT已經出現了。SUN當時已經建立了一套基本的可移植控制項類,這些類映射到不同作業系統上的原生視窗組件(native widget),當時的AWT還滿是漏洞,遠不能稱為可靠,還需要SUN的coder們去修補。然後Amy被僱傭了,她承諾通過輕量級方案解決所有視窗組件的問題,以此說服SUN管理層讓她當了GUI開發部門的頭頭。隨後Amy僱傭了所有她過去在Parc-Place的舊朋友,讓他們來開發Swing。

    在IBM,VisualAge for Java最初是用Smalltalk(用的是原生視窗組件)寫的,當將這些工具向Java程式碼程式庫遷移時,他們需要一套視窗組件。IBM這邊的開發人員都是原來搞Smalltalk的那一批人,他們對管理層要求用Swing來構建WebSphere Studio工具都非常不情願。“Swing是個可怕的充滿缺陷的怪獸“。因此開始了一個新的項目,把他們的Smalltalk原生視窗組件移植到Java上去。這個工具集後來被成為SWT,S開始是Simple的縮寫,不過後來變成了Standard的縮寫。這個項目獲得了成功,被運用在發布的 VisualAge Micro Edition產品中。他們當時發現在Swing讀事件隊列的時候用了一種可能留下記憶體漏洞的方式,而不得不採用他們自己的查詢 Windows事件隊列的迴圈,以糾正這個錯誤。這促成了他們關於SWT和 AWT/Swing不能共存的決定。他們把這個工具包放到了Eclipse中,這是一個來自於早期Visual Age的工具平台。

    你應該已經從上述的故事中對三者的曆史有了大概的瞭解,尤其是SWT。現在你也許會覺得,IBM建立SWT的理由是合理的而Swing應該沿用SWT採用的方式。這樣的觀點是片面的,當你深入瞭解到Java的本質之後,你會發現其實並不像你想象的那麼簡單。

先決條件

什麼才是Java本質的,影響到工具集設計的特徵呢?或者說,什麼才是Java GUI工具集設計的先決條件呢?

    答案來自於Sun對Java的承諾之一:write once, run anywhere(一次編寫,隨處運行)。這是Java不同於其他語言的優勢所在。在Java被建立之前,軟體的跨平台效能是開發人員,特別是那些希望對多平台提供支援的開發人員的夢魘。在當今的生活中Internet的使用已經相當的普遍了,在世界不同角落的人們在不同的平台上工作著。軟體供應商為不同的作業系統提供支援是再平凡不過的事情。Java的write-once-run-anywhere(WORA)承諾顯然減輕了開發人員的負擔,極大地提高了軟體開發的生產力。

    然而編寫跨平台的應用程式,你必須使用支援平台無關性的標準庫。這些標準庫包括語言支援,公用用途,網路,I/O和GUI工具集等。所以當Sun開始設計GUI工具集的時候,首要任務就是考慮一個設計良好的平台無關的API。AWT和Swing都被小心地設計以保證平台相容性。SWT則相反,它在設計之初並不以擴充性為原則,它為一個專有的IDE Visual Age for Java而設計,Windows作為這個IDE的首選運行環境擁有很高的優先順序考量。SWT API類似於WIndows,通常它並不如Swing的擴充性好,儘管Steve Northover,SWT之父,辯稱SWT是平台無關的,你可以很容易地發現許多Windows API的痕迹。

區別

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

Terms
    首先讓我圖解兩個數學概念:最大公約數和最小公倍數。如,三個集合代表不同的作業系統。相交的部分是最大公約數,合并的部分是最小公倍數。

現在讓我們來考察Java GUI工具集AWT,SWT和Swing的組件類型和特徵

AWT
   AWT組件集遵循最大公約數原則,即AWT只擁有所有平台上都存在的組件的公有集合。所以你在AWT中無法擷取如表或樹等進階組件,因為它們在某些平台上不支援。AWT的組件特徵同樣遵循這一原則。它只提高平台上公有的特徵。例如AWT按鈕不能附著圖片,因為在Motif平台上,按鈕是不支援圖片的。

由於它低劣的組件集和特徵,AWT無法吸引開發人員。它是Sun不推薦使用的,只是為了確保向下相容和支援Swing。

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來得豐富。

Swing

    Swing是三者中最強大和靈活的。在組件類型上,它遵循最大公約數原則。由於Swing可以控制自身GUI系統的全部並有很好的可擴充和靈活性,它幾乎可以建立所有你想象得到的組件。唯一的限制是它的AWT容器。在Swing中你還不能跨平台地實現真正的透明化和不規則矩形視窗,因為Swing依賴於AWT頂層容器例如Applet, Window, Frame and Dialog等。除此之外,Swing幾乎實現了所有平台上的標準組件。

    在組件特徵上,Swing遵循最小公倍數原則。它擁有所有平台上可提供的組件特徵。不僅如此,你還可以繼承已有的Swing組件並添加新的特性。

   上面比較主要是在API層級上的。讓我們將比較的焦點轉移到實現細節上。Swing和SWT/AWT的區別是Swing是純Java實現,而SWT和AWT是Java和JNI的混合。當然,它們的目標都是相同的,提供一個跨平台的APIs。然而為了達到這一點,SWT和AWT不得不犧牲一些組件和特性以提供一個通用的APIs。

AWT
    一個AWT組件通常是一個包含了對等體介面類型引用的組件類。這個引用指向本地對等體實現。舉java.awt.Label為例,它的對等體介面是LabelPeer。LabelPeer是平台無關的。在不同平台上,AWT提供不同的對等體類來實現LabelPeer。在Windows上,對等體類是WlabelPeer,它調用JNI來實現label的功能。這些JNI方法用C或C++編寫。它們關聯一個本地的label,真正的行為都在這裡發生。作為整體,AWT組件由AWT組件類和AWT對等體提供了一個全域公用的API給應用程式使用。一個組件類和它的對等體介面是平台無關的。底層的對等體類和JNI代碼是平台相關的。

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的方法更加明智。

SWING

    到了Swing這裡,一切就變得清晰和直接了。除了頂層容器,Swing的實現不依賴於具體平台。它掌管了所有的控制和資源。Swing所需要的是事件輸入來驅動系統,以及承接自頂層AWT容器的圖形處理,字型和顏色。普通的Swing組件可以看作是AWT容器的一塊邏輯地區。它們並沒有註冊對等體。所有添加到同一頂層容器的Swing組件共用它的AWT對等體以擷取系統資源,如字型,圖形處理等。Swing將組件自己的資料結構儲存在JVM的空間中。它完全由自己管理畫圖處理,事件分發和組件布局。

    由於AWT和SWT都持有對本機群組件的引用,它們必須以正確的方式釋放這些引用以避免記憶體泄露和JVM崩潰。AWT將絕大多數資源管理工作交給系統,將開發人員從單調乏味的資源管理中解救出來。然而這使得AWT的實現複雜化了。一旦它實現了,開發人員很少有機會犯錯誤並使他們的程式崩潰。

    SWT用的是另一種方法。大體上,SWT讓開發人員自己來管理資源。它的一條著名的規則是:誰建立,誰釋放。因此開發人員必須謹慎地顯式調用dispose方法釋放每一個由他建立的組件和資源。這簡化了SWT的實現模型,但把開發人員擺在了因錯誤編碼而易於造成程式崩潰這一風險之上。

類比方式的區別

   Swing和SWT在它們的實現上都使用了類比。SWT只類比平台上缺失的組件。區別是SWT的類比更像是AWT的Canvas實現的類比。SWT的Composite類有它自己在作業系統中相應的對等體。它從自己的對等體中獲得所有它所需要的資源形處理的對象,字型和顏色等。它直接從作業系統擷取所有的事件並進行處理。然而,Swing組件在作業系統中沒有相應的對等體。它只是一塊頂層容器中的邏輯地區,實際上它從頂層容器的對等體中借用資源。Swing的事件並不是底層系統產生的事件。它們實際是由頂層容器處理AWT事件所產生的偽事件。我們會在稍後的事件部分中詳細介紹它。

圖形層結構
    另一個不同之處是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組件很可能遮蓋菜單。

布局管理器

    並不是三者中的所有部分都是不同的。布局管理器是一個例外。開發GUI應用程式,當容器改變大小的時候,組件需要重定位或改變大小。在傳統的程式設計語言中,這依靠監聽大小改變的事件來實現。相應的片段散落在原始碼的各個角落降低了程式的可讀性。Java引入了將布局代碼封裝的思路,稱之為布局管理器。當布局管理器對象被設定到一個容器中,它自動處理大小改變的事件。當大小改變時,管理器的布局方法被調用以重定位子組件或調整它們的形狀。

    AWT,SWT和Swing都以這樣的方式來組織,而都有它們各種獨特的布局管理器。由於AWT和Swing擁有一個共同的超類java.awt.Component,它們的布局管理器可以交替地使用。

Look And Feel觀感

    包括SWT和AWT在內的本地工具集並不支援Look And Feel機制。它們將組件捆綁在作業系統上,有其優勢和劣勢。其中的一個劣勢是它們不支援可插拔的Look And Feel。將繪製處理交由作業系統完成剝奪了它們實現自訂群組件Look And Feel的能力,也就使得它們無法提供這種機制。Look And Feel機制越來越成為GUI工具集中不可缺少的一部分。

    Swing擁有很好的Look And Feel支援。你甚至可以動態地改變Swing應用程式的Look And Feel,鑒於AWT和SWT將組件控制完全交給作業系統處理,這是它們所無法超越的任務。我曾經聽很多人抱怨過Sun在Swing上的設計。他們覺得Swing為什麼不像SWT那樣沿用AWT的思路呢?事實上,Look And Feel機制正是Swing走到這個方向上的原因之一。如果Swing遵循的是封裝已有的組件並類比不存在的組件的路線,那它就無法提供Look And Feel機制。因為提供Look And Feel機制是本地策略所無法完成的任務。

Graphics and Fonts圖形和字型
    Swing作為一個仿生系統,它的圖形工具集較之AWT和SWT強大許多。Swing基於其自身系統中的兩個基礎組件群:Java 2D和AWT。Java 2D在Java中是強大的類庫,它為進階影像處理,顏色管理,圖形繪製和填充,座標系變換和字型產生提供豐富的特性。相較之下,AWT和AWT僅對這些特性提供有限訪問,它們是相對原始和低級的。

JavaBeans Specification Conformity JavaBeans規範一致性
    Swing和AWT在設計之初就秉承了JavaBeans規範,它們的組件類與JavaBeans規範一致。然而SWT並沒有很好的遵循這一規範。例如,在SWT的組件類中沒有無參的構造器。每個組件都必須至少擁有一個單參數的構造器。這個參數就是父組件的引用。這意味著無論何時組件被建立,它都直接被添加到一棵組件樹中。一個組件無法脫離於登入的本地對等體而存在。這樣,SWT就能讓由編程者建立的組件在display的dispose方法被調用的時候自動被釋放。

More on Resource Management更多在資源管理方面的內容
    SWT的組件構造器策略可以排除某些記憶體泄露的可能性。AWT在資源管理方面也有類似的問題。但它採用了不同的方式解決。當AWT組件被建立的時候,相應的對等體並不會立即被建立。即便它被添加到一棵組件樹,而如果這棵樹還不可見,那麼對等體仍不會被建立。只有當頂層容器被設為可見,這些對等體才會被建立。建立對等體的方法通常在addNotify中,它們通常遞迴地調用父組件的addNotify直到整棵組件樹上的對等體都被建立了。當頂層容器由dispose方法銷毀的時候,一個對應的方法removeNotify將會被遞迴地調用以釋放這些對等體。這樣,AWT在不由開發人員介入的情況下管理了它的資源。

Event System事件系統
    一個事件要求特定的動作被執行,它被作為訊息由外界或系統自身發送給GUI系統。這些事件包括來自電腦裝置如滑鼠鍵盤和網路連接埠的I/O中斷,以及GUI系統的邏輯事件觸發,比如一個按鈕的ActionEvent事件。

Single-Threaded vs Multiple-Threaded 單線程 vs 多線程
事件分發遵循兩種不同的模型。單線程分發模型和多線程分發模型。

    在單線程分發模型中,一個事件從隊列中抽出並在同一個線程中被立即處理。事件處理後,緊跟著的下一個事件再被抽出並繼續下一輪的迴圈。在多線程分發模型中,從隊列中擷取事件的線程啟動另一個被稱作任務線程的線程,並把事件交給它處理。而擷取事件的線程並不等待處理線程的結束。它簡單的擷取下一個線程並分發它。

    事件處理通常涉及應用程式的資料變化。而且這些資料經常是組件需要顯示的。多線程分發很容易產生同步問題,它產生多個可能互相干擾的事件處理線程。在一個穩定的GUI系統中,組件應該能夠保持視圖與模型間的同步。由於同步問題的出現,多執行緒模式要求開發人員擁有更多並發編程的經驗。而對於普通編程人員,造成同步錯誤是很容易的。因此許多GUI系統並不使用這一模型。

   單執行緒模式通過強制事件序列化地被處理提供了實際上的同步。AWT,SWT和Swing 都採用了這一模型來分發事件。但單執行緒模式也會有它自己的問題。其中之一就是線程專註。既然所有的事件都在一個線程中被分發,如果其中的一個事件的處理費時過久,將會拖延下一個事件的抽取和執行。如果有一個PAINT事件被延後,那麼在螢幕上就會呈現為無法響應。這經常使使用者感覺到軟體很慢。許多這樣的低效程式是由於開發人員的經驗不足造成的。他們的做法是將耗時任務填充到監聽器方法中。由於這種錯誤的編程方式在Swing中大量被使用而尤為突出,這也是它慢而醜陋的壞名聲的由來之一。實際上,如果你懂得使用線程,Swing應用程式可以表現出很高的響應度。

Thread Safety安全執行緒

    上述問題的解決方案是啟動一個單獨的工作者線程來完成耗時處理,這樣就能把事件分發線程釋放處理以繼續運作。如多執行緒模式中所做的那樣,然而這同樣會引入在多執行緒模式中出現的同步問題。許多GUI工具集都有自己先天性的機制來解決這一問題,例如,在組件樹上的組合鎖。開發人員不需要為如何安全編程而操心。這樣的工具集被成為安全執行緒的。AWT就是其中之一。

    然而,由於不必要的同步使得建立這樣的GUI系統過於負責並造成了額外的開銷。因此,Swing和SWT被設計為非安全執行緒的,這意味著開發人員必須謹慎地實現他們的多線程任務。SWT和Swing在運行時安全執行緒行為上有一個小小的區別。SWT總是檢查改變組件的操作是否在事件分發線程上執行。這樣,開發人員就能夠發現同步問題。而Swing不這樣,這是Swing的一個不知之初,這其實並不難實現。

Event Dispatching Thread事件分發線程

    AWT讀取作業系統中的基本事件並在java代碼中處理它們。AWT事件分發線程被命名為?AWT-{OS}-Thread。這個線程由AWT系統隱式啟動。當AWT應用程式啟動時,這個線程在背後啟動,在作業系統上抽取和移除事件。當諸如按鈕動作這樣的邏輯事件被觸發時,它傳遞給註冊在按鈕上的操作監聽器。開發人員也能為AWT組件編寫滑鼠,鍵盤和繪製事件的事件監聽器。這通常通過擴充AWT Canvas組件來完成。這一組件支援了所有已提供的事件,而且你可以通過重寫事件處理方法,實現一個自訂的組件。

    然而,在Swing中,這是一個不同的線程。Swing把AWT事件作為自身事件系統的一個輸入。它擷取AWT事件並做一些初始化處理,產生一個對應的Swing事件並把它放到自己的事件隊列上。Swing也有自己的事件分發線程,通常命名為EventQueue-0。這個線程從事件隊列中抽取Swing事件,就如同AWT從作業系統中抽取那樣。然後它把事件分發給目標組件。通常事件首先被分發給組件的頂層容器,然後由頂層容器的dispatch方法處理,它可能被再分發或重新導向到一個Swing組件,在那裡繼續由自己的監聽器進行處理。

    例如,當一個滑鼠移過一個JButton或JFrame時,一個指向JFrame的AWT事件在AWT線程上觸發。AWT線程檢查它是否需要作更多的處理,然後把它封裝成一個Swing的MouseEvent對象並把它添加到EventQueue隊列中。當獲得MouseEvent事件後,EventQueue-0抽取這個事件並判斷出目標Swing組件。這裡,這個組件是JButton。然後它產生了一個包含相對座標位置和事件來源的新的MouseEvent重新導向到這個JButton上,然後調用這個JButton的dispatch以繼續分發。JButton的dispatch過濾事件給特定的方法最終實現由滑鼠監聽器在該點上的分發的點擊。

    SWT更類似於AWT。唯一的區別是它要求開發人員顯式地書寫事件迴圈代碼。然而底層的實現細節是不同於AWT的。看看SWT的讀取和分發事件代碼,它會讓你想起MFC的代碼風格。

Event Listener事件監聽器
   AWT,SWT和Swing都有相似的事件監聽器模型。它們都使用觀察者模式,組件和監聽器的串連方式是把監聽器添加到組件上,這組成了一個對象網路的模型。當事件被觸發並分發給組件,組件調用它的監聽器以處理事件。一個監聽器也可以繼續分發事件給後續的處理,或產生一個新的事件並把它廣播到網路中的其他節點上。基本上有兩種不同的廣播事件方式。一種是同步調用監聽器。另一種是非同步地將事件發送回隊列,它將在新一輪的事件分發中被分發出去。

    除了直接發送給隊列的方式,Swing還有一些其他的分發非同步事件的方法。其中之一是調用SwingUtilities 或EventQueue 的invokeLater,這一方法封裝一個Runnable對象到事件中並把它發送給事件隊列。這確保了Runnable的run方法能在事件分發線程上執行,保證了安全執行緒。實際上,Swing的Timer好SwingWorker基於這一機制實現。SWT也有相應的發送非同步事件的方式。它的invokeLater的對應方法是display.asyncExec,它以一個Runnable對象作為參數。

我從一個技術層面給出了他們優劣勢上的一個清單,以結束本文。

AWT
AWT是Sun不推薦使用的工具集。然而它在許多非案頭環境如移動或嵌入式裝置中有著自己的優勢。
更少的記憶體。它對運行在有限環境中的GUI程式的開發,是合適的。

1.更少的啟動事件。由於AWT組件是本地由作業系統實現的。絕大多數的二進位代碼已經在如系統啟動的時候被預裝載了,這降低了它的啟動事件。

2.更好的響應。由於本機群組件由作業系統渲染。

3.從java 1.x時代就為JRE支援的標準GUI工具集,你不用單獨安裝它,你不用擔心平台差異的問題。

4.成熟穩定的。它能夠正常工作並很少使你的程式崩潰。

然而,事物都有它們不好的一面。讓我們來例數它吧。

1. 更少的組件類型。表和樹這些重要的組件缺失了。它們是傳統型應用程式中普遍使用的。

2.缺乏豐富的組件特徵。按鈕不支援圖片附著。這很明顯是它遵循的設計原則造成的。

3.不支援Look And Feel。AWT被設計為使用本機群組件。因此,它依賴系統來提供Look And Feel支援。如果目標系統並不支援這一特性,那麼AWT將無法改變它的Look And Feel。

4.無擴充性。AWT的組件是本機群組件。JVM中的AWT類執行個體實際只是包含本機群組件的引用。唯一的擴充點是AWT的Canvas組件,你可以從零開始建立自訂群組件。然而無法繼承和重用一個已有的AWT組件。

SWT
   SWT有如下優勢:

1.豐富的組件類型。SWT提供了種類繁多的組件,從基礎組件如按鈕和標籤到進階的表格和樹。

2.相對的豐富組件特性。儘管SWT也遵循最大公倍數原則,它採用類比的方式重新設計了對更多組件特性的支援。所以同AWT相比,它有著相對豐富的組件特性。

3.更快的回應時間。基於和AWT同樣的原因,SWT組件封裝了本機群組件,由作業系統實現渲染。作業系統通常對渲染處理做了最佳化,儲存GUI二進位代碼為標準庫,減少了記憶體的使用,提高了響應效能。

4.更少的記憶體消耗。既然作業系統為本機群組件提供了最佳化,這一點就容易理解了。

不足之處:

    1.不在JRE的標準庫中。因此你必須將它和你的程式捆綁在一起,並為你所要支援的每個作業系統建立單獨的安裝程式。

2.不夠成熟和穩定。SWT因其設計上的一些缺陷,如資源管理,Windows友好等,被認為是不穩定的。它可以在Windows上表現得很好,但在其他動作系統上,它經常是不穩定且容易崩潰的。這很大程度上是因為它把資源管理交給開發人員來處理,而並不是所有的開發人員能夠正確地處理這些。

3.在非Windows平台下的效能不高。如同第2點提到的,SWT被設計為與Windows API相協調的,這導致了在非Windows平台上的效能問題,糟糕的UI感官,不穩定甚至記憶體泄露。

4.無Look And Feel 支援。和AWT同樣的原因。

5.不可擴充,和AWT同樣的原因。在SWT中你可以通過有限的方式擴充一個組件,例如,監聽PAINT事件並添加自訂繪圖到組件上,但鑒於你只能控制繪製處理的一部分,這是十分有限的。你也只能在作業系統繪製完組件後補充,這並不能很好支援自訂。許多應用程式在自訂行為上有很高的要求。

SWING
    Swing是三者中最強大的GUI工具集。它和另外兩者相比同樣有自己的優劣勢。

1、豐富的組件類型。Swing提供了非常廣泛的標準組件。這些組件和SWT一樣豐富。基於它良好的可擴充性,除了標準組件,Swing還提供了大量的第三方組件。許多商業或開源的Swing組件庫在開發多年後都已經可以方便地擷取了。

2、豐富的組件特性。Swing不僅包含了所有平台上的特性,它還支援根據程式所啟動並執行平台來添加額外特性。Swing組件特性遵循特定原則,易於擴充,因此能夠提供較SWT和AWT更多的功能。

3、好的組件API模型支援。Swing遵循MVC模式,這是一種非常成功的設計模式。它的API成熟並設計良好。經過多年的演化,Swing組件APIs變得越來越強大,靈活和可擴充。它的API設計被認為是最成功的GUI API之一。較之SWT和AWT更物件導向,也更靈活而可擴充。

4、出色的Look And Feel支援。MVC設計模型允許Swing分離組件視圖和它的資料模型。它有進階的UI委託來將UI渲染委託給UI類。這些類被註冊到一個展現特定的Look And Feel的對象上。已經有上百個Look And Feel 可以提高各種各樣的GUI風格。你甚至可以基於其他人的成果編寫組件的Look And Feel 。

5、標準的GUI庫。Swing和AWT一樣是JRE中的標準庫。因此,你不用單獨地將它們隨你的應用程式一起分發。它們是平台無關的,所以你不用擔心平台相容性。

6、成熟穩定。Swing已經開發出來7年之久了。在Java5之後它變得越來越成熟穩定。由於它是純Java實現的,不會有SWT的相容性問題。Swing在每個平台上都有相同的效能,不會有明顯的效能差異。

7、可擴充和靈活性。Swing完全在Java空間中實現。它可以控制它所需要的一起。Swing基於MVC的結構使得它可以發揮Java作為一門物件導向語言的優勢。它提供了許多向外延展群組件的方法。讓我們來列舉一下:

A.繼承已有組件;
B.靠複合組件的方式擴充。
C.從零開始使用JComponent編寫自訂群組件;
D.使用渲染器和編輯器機制擴充複製的Swing組件,如JList,JComboBox,JTable,JTree等;
E.基於已有Look And Feel 或從零開始建立新的Look And Feel;
F.使用LayeredPane,GlassPane或拖放機制開發進階的組件,例如浮動的固定組件,自訂快顯視窗,自訂菜單等。

8、總體上良好的效能。Swing的速度是其為人詬病的一點。然而隨著JRE的開發,Swing的效能如今已經有了很大的提高。特別是Java5之後,Swing的總體速度能夠接近本地小控制項系統。

一個GUI的速度總是從兩個方面被衡量:回應時間和資料反饋時間。

    響應事件指從事件任務出現到組件更新UI的這段時間。例如按下一個按鈕,拖動一個組件,改變一個多標籤面板等。在這個方面本機群組件總能比類比組件有更好的響應。AWT和SWT通常比Swing表現出更好的回應時間。然而事實並非總是如此。這取決於作業系統。如果本機群組件沒有被良好的實現,那結果就是相反的。例如Windows開發了不錯的GUI庫,而Linux平台通常差得較遠。SWT可能在Windows上表現得比Swing好,而在Linux上表現得比Swing差。也就是說,AWT/SWT的效能決定於底層平台。隨著JRE的開發,Swing的響應效能能夠隨著JVM的最佳化,更好的實現方式,以及圖形硬體加速而得到長足的改進。在Windows上,Java6的Swing可以媲美SWT的效能。在非Windows環境中,Swing可以表現出更好的回應時間。

     資料輸送時間是指用於將應用程式資料傳遞給UI組件所需要的時間。例如,一個學生管理系統要求從資料庫中裝載學生資訊並在一個表格中顯示出來。花費在從記憶體到表格組件的資料傳遞時間被稱為資料輸送時間.在這個方面,Swing通常比其他二者的效能更好。或許當資料量不大的情況下並不明顯。但當海量的資料被輸送給表格的時候,這一點就顯而易見了。為了理解這一點,提醒你注意JVM和本地作業系統是兩個分離的運行時環境。由於JNI的調用在兩個環境中跨越式地發生,通常比一個普通的Java調用花費更長的時間。通常這包含兩個處理。一個是Java資料結構轉換為本機資料結構,另一個是方法返回時的本機資料結構轉換為Java對象。其他的效能開銷暫時忽略不計。當一個大範圍數組的資料從本機群組件中輸送過來,大量反覆的JNI調用將極大地拖垮效能。

     Swing的另一個優勢是它有許多的組件模型以提高輸送的效能。例如TableModel被映射為兩個維度上的數組。這樣,在Swing組件中甚至不需要進行資料方式的轉換。Swing直接將應用程式資料顯示在螢幕上,節省了在資料轉換上所花費的事件。

Swing也有不足之處:

     比AWT和SWT更多的記憶體消耗。Swing自己實現了所有組件。因此,它在運行時裝載了大量的類。一些其他的問題來源於小的可變對象的建立,如Rectangle,Point,這些對象基於同步的考慮通常不可重用。Java在堆上建立所以對象。小的對象通常導致了額外的堆空間消耗。許多小的對象較之大對象更難以有效地被記憶體回收。因此,Swing應用程式通常無法及時回收大而小的對象。這種情況的普遍就會導致效能下降。

    更多的啟動時間。現在JVM已經快得多了。許多人甚至揚言它可以媲美C++的實現。但多數的Java應用程式還是看上去很慢。實際上,Java效能的很多問題來源於類裝載機制。這是一個I/O操作,故而能夠明顯地降低Java應用程式的速度。也許這是每個動態連結系統中都要面對的問題吧。Swing通常包含了上千個Swing類的使用,在Swing應用程式可以顯示它的主視窗之前,它比AWT或SWT裝載了多得多的類。這嚴重降低了Swing的啟動時間。這種問題也許會相對好一點如果Swing的類是以共用系統庫的方式預先載入的。

       上述的比較總的來說是技術上的總結。相對其他方面的因素也會影響你對一個工具集的選擇。例如,文檔,支援,學習曲線和社區等,但既然我們關注的是技術層面,就不在這裡講的太多了。

 

轉自:http://dolive.javaeye.com/blog/202758

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.