AWT,SWT和Swing都有相似的事件監(jiān)聽器
如多線程模型中所做的那樣,然而這同樣會(huì)引入在多線程模型中出現(xiàn)的同步問題。許多GUI工具集都有自己先天性的機(jī)制來(lái)解決這一問題,例如,在組件樹上的組合鎖。開發(fā)者不需要為如何安全編程而操心。這樣的工具集被成為線程安全的。AWT就是其中之一。
然而,由于不必要的同步使得建立這樣的GUI系統(tǒng)過(guò)于負(fù)責(zé)并造成了額外的開銷。因此,Swing和SWT被設(shè)計(jì)為非線程安全的,這意味著開發(fā)者必須謹(jǐn)慎地實(shí)現(xiàn)他們的多線程任務(wù)。SWT和Swing在運(yùn)行時(shí)線程安全行為上有一個(gè)小小的區(qū)別。SWT總是檢查改變組件的操作是否在事件分發(fā)線程上執(zhí)行。這樣,開發(fā)者就能夠發(fā)現(xiàn)同步問題。而Swing不這樣,這是Swing的一個(gè)不知之初,這其實(shí)并不難實(shí)現(xiàn)。
Event Dispatching Thread事件分發(fā)線程
AWT讀取操作系統(tǒng)中的基本事件并在java代碼中處理它們。AWT事件分發(fā)線程被命名為?AWT-{OS}-Thread。這個(gè)線程由AWT系統(tǒng)隱式啟動(dòng)。當(dāng)AWT應(yīng)用程序啟動(dòng)時(shí),這個(gè)線程在背后啟動(dòng),在操作系統(tǒng)上抽取和移除事件。當(dāng)諸如按鈕動(dòng)作這樣的邏輯事件被觸發(fā)時(shí),它傳遞給注冊(cè)在按鈕上的操作監(jiān)聽器。開發(fā)者也能為AWT組件編寫鼠標(biāo),鍵盤和繪制事件的事件監(jiān)聽器。這通常通過(guò)擴(kuò)展AWT Canvas組件來(lái)完成。這一組件支持了所有已提供的事件,而且你可以通過(guò)重寫事件處理方法,實(shí)現(xiàn)一個(gè)自定義的組件。
然而,在Swing中,這是一個(gè)不同的線程。Swing把AWT事件作為自身事件系統(tǒng)的一個(gè)輸入。它獲取AWT事件并做一些初始化處理,產(chǎn)生一個(gè)對(duì)應(yīng)的Swing事件并把它放到自己的事件隊(duì)列上。Swing也有自己的事件分發(fā)線程,通常命名為EventQueue-0。這個(gè)線程從事件隊(duì)列中抽取 Swing事件,就如同AWT從操作系統(tǒng)中抽取那樣。然后它把事件分發(fā)給目標(biāo)組件。通常事件首先被分發(fā)給組件的頂層容器,然后由頂層容器的 dispatch方法處理,它可能被再分發(fā)或重定向到一個(gè)Swing組件,在那里繼續(xù)由自己的監(jiān)聽器進(jìn)行處理。
例如,當(dāng)一個(gè)鼠標(biāo)移過(guò)一個(gè)JButton或JFrame時(shí),一個(gè)指向JFrame的AWT事件在AWT線程上觸發(fā)。AWT線程檢查它是否需要作更多的處理,然后把它包裝成一個(gè)Swing的MouseEvent對(duì)象并把它添加到EventQueue隊(duì)列中。當(dāng)獲得MouseEvent事件后,EventQueue-0抽取這個(gè)事件并判斷出目標(biāo)Swing組件。這里,這個(gè)組件是JButton。然后它產(chǎn)生了一個(gè)包含相對(duì)坐標(biāo)位置和事件源的新的MouseEvent重定向到這個(gè)JButton上,然后調(diào)用這個(gè) JButton的dispatch以繼續(xù)分發(fā)。JButton的dispatch過(guò)濾事件給特定的方法最終實(shí)現(xiàn)由鼠標(biāo)監(jiān)聽器在該點(diǎn)上的分發(fā)的點(diǎn)擊。
SWT更類似于AWT。唯一的區(qū)別是它要求開發(fā)者顯式地書寫事件循環(huán)代碼。然而底層的實(shí)現(xiàn)細(xì)節(jié)是不同于AWT的??纯碨WT的讀取和分發(fā)事件代碼,它會(huì)讓你想起MFC的代碼風(fēng)格。
Event Listener事件監(jiān)聽器
AWT,SWT和Swing都有相似的事件監(jiān)聽器模型。它們都使用觀察者模式,組件和監(jiān)聽器的連接方式是把監(jiān)聽器添加到組件上,這組成了一個(gè)對(duì)象網(wǎng)絡(luò)的模型。當(dāng)事件被觸發(fā)并分發(fā)給組件,組件調(diào)用它的監(jiān)聽器以處理事件。一個(gè)監(jiān)聽器也可以繼續(xù)分發(fā)事件給后續(xù)的處理,或產(chǎn)生一個(gè)新的事件并把它廣播到網(wǎng)絡(luò)中的其他節(jié)點(diǎn)上?;旧嫌袃煞N不同的廣播事件方式。一種是同步調(diào)用監(jiān)聽器。另一種是異步地將事件發(fā)送回隊(duì)列,它將在新一輪的事件分發(fā)中被分發(fā)出去。
除了直接發(fā)送給隊(duì)列的方式,Swing還有一些其他的分發(fā)異步事件的方法。其中之一是調(diào)用SwingUtilities 或EventQueue 的invokeLater,這一方法包裝一個(gè)Runnable對(duì)象到事件中并把它發(fā)送給事件隊(duì)列。這確保了Runnable的run方法能在事件分發(fā)線程上執(zhí)行,保證了線程安全。實(shí)際上,Swing的Timer好SwingWorker基于這一機(jī)制實(shí)現(xiàn)。SWT也有相應(yīng)的發(fā)送異步事件的方式。它的 invokeLater的對(duì)應(yīng)方法是display.asyncExec,它以一個(gè)Runnable對(duì)象作為參數(shù)。
AWT
AWT是Sun不推薦使用的工具集。然而它在許多非桌面環(huán)境如移動(dòng)或嵌入式設(shè)備中有著自己的優(yōu)勢(shì)。
更少的內(nèi)存。它對(duì)運(yùn)行在有限環(huán)境中的GUI程序的開發(fā),是合適的。
1.更少的啟動(dòng)事件。由于AWT組件是本地由操作系統(tǒng)實(shí)現(xiàn)的。絕大多數(shù)的二進(jìn)制代碼已經(jīng)在如系統(tǒng)啟動(dòng)的時(shí)候被預(yù)裝載了,這降低了它的啟動(dòng)事件。
2.更好的響應(yīng)。由于本地組件由操作系統(tǒng)渲染。
3.從java 1.x時(shí)代就為JRE支持的標(biāo)準(zhǔn)GUI工具集,你不用單獨(dú)安裝它,你不用擔(dān)心平臺(tái)差異的問題。
4.成熟穩(wěn)定的。它能夠正常工作并很少使你的程序崩潰。
然而,事物都有它們不好的一面。讓我們來(lái)例數(shù)它吧。
1. 更少的組件類型。表和樹這些重要的組件缺失了。它們是桌面應(yīng)用程序中普遍使用的。
2.缺乏豐富的組件特征。按鈕不支持圖片附著。這很明顯是它遵循的設(shè)計(jì)原則造成的。
3.不支持Look And Feel。AWT被設(shè)計(jì)為使用本地組件。因此,它依賴系統(tǒng)來(lái)提供Look And Feel支持。如果目標(biāo)系統(tǒng)并不支持這一特性,那么AWT將無(wú)法改變它的Look And Feel。
4.無(wú)擴(kuò)展性。AWT的組件是本地組件。JVM中的AWT類實(shí)例實(shí)際只是包含本地組件的引用。唯一的擴(kuò)展點(diǎn)是AWT的Canvas組件,你可以從零開始創(chuàng)建自定義組件。然而無(wú)法繼承和重用一個(gè)已有的AWT組件。
SWT
SWT有如下優(yōu)勢(shì):
1.豐富的組件類型。SWT提供了種類繁多的組件,從基礎(chǔ)組件如按鈕和標(biāo)簽到高級(jí)的表格和樹。
2.相對(duì)的豐富組件特性。盡管SWT也遵循最大公倍數(shù)原則,它采用模擬的方式重新設(shè)計(jì)了對(duì)更多組件特性的支持。所以同AWT相比,它有著相對(duì)豐富的組件特性。
3.更快的響應(yīng)時(shí)間?;诤虯WT同樣的原因,SWT組件包裝了本地組件,由操作系統(tǒng)實(shí)現(xiàn)渲染。操作系統(tǒng)通常對(duì)渲染處理做了優(yōu)化,保存GUI二進(jìn)制代碼為標(biāo)準(zhǔn)庫(kù),減少了內(nèi)存的使用,提高了響應(yīng)性能。
4.更少的內(nèi)存消耗。既然操作系統(tǒng)為本地組件提供了優(yōu)化,這一點(diǎn)就容易理解了。
以上就是AWT,SWT和Swing都有相似的事件監(jiān)聽器的內(nèi)容。
【編輯推薦】















 
 
 
 
 
 
 