日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺析Swing線程中的LookupEvent

所有前面的這些解決方案都存在一個(gè)共同的致命缺陷--企圖在持續(xù)地改變線程的同時(shí)表示一個(gè)任務(wù)的功能集。但是改變線程需要異步的模型,而線程異步地處理Runnable。問題的部分原因是我們在企圖在一個(gè)異步的線程模型之上實(shí)現(xiàn)一個(gè)同步的模型。這是所有Runnable之間的鏈和依賴,執(zhí)行順序和內(nèi)部類scooping問題的根源。如果我們可以構(gòu)建真正的異步,我們就可以解決我們的問題并極大地簡化Swing線程。

讓我們考慮一下像Java消息服務(wù)(JMS)這樣的基于消息的系統(tǒng),因?yàn)樗鼈兲峁┝嗽诋惒江h(huán)境中功能組件之間的松散耦合。消息系統(tǒng)觸發(fā)異步事件,正如在Enterprise Integration Patterns 中描述的。感興趣的參與者監(jiān)聽該事件,并對事件做成響應(yīng)--通常通過執(zhí)行它們自己的一些代碼。結(jié)果是一組模塊化的,松散耦合的組件,組件可以添加到或者從系統(tǒng)中去除而不影響到其它組件。更重要的,組件之間的依賴被最小化了,而每一個(gè)組件都是良好定義的和封裝的--每一個(gè)都僅對自己的工作負(fù)責(zé)。它們簡單地觸發(fā)消息,其它一些組件將響應(yīng)這個(gè)消息,并對其它組件觸發(fā)的消息進(jìn)行響應(yīng)。

現(xiàn)在,我們先忽略線程問題,將組件解耦并移植到異步環(huán)境中。在我們解決了異步問題后,我們將回過頭來看看線程問題。正如我們所將要看到的,那時(shí)解決這個(gè)問題將非常容易。

讓我們還拿前面引入的例子,并把它移植到基于事件的模型。首先,我們把lookup調(diào)用抽象到一個(gè)叫LookupManager的類中。這將允許我們將所有UI類中的數(shù)據(jù)庫邏輯移出,并最終允許我們完全將這兩者脫耦。下面是LookupManager類的代碼:

 
 
 
  1. classLookupManager{  
  2. privateString[]lookup(Stringtext){  
  3. String[]results=...  
  4. //databaselookupcode  
  5. returnresults  
  6. }  

現(xiàn)在我們開始向異步模型轉(zhuǎn)換。為了使這個(gè)調(diào)用異步化,我們需要抽象調(diào)用的返回。換句話,方法不能返回任何值。我們將以分辨什么相關(guān)的動(dòng)作是其它類所希望知道的開始。在我們這個(gè)例子中最明顯的事件是搜索結(jié)束事件。所以讓我們創(chuàng)建一個(gè)監(jiān)聽器接口來響應(yīng)這些事件。該接口含有單個(gè)方法lookupCompleted()。下面是接口的定義:

 
 
 
  1. interfaceLookupListener{  
  2. publicvoidlookupCompleted(Iteratorresults);  
  3. }  

遵守Java的標(biāo)準(zhǔn),我們創(chuàng)建另外一個(gè)稱作LookupEvent的類包含結(jié)果字串?dāng)?shù)組,而不是到處直接傳遞字串?dāng)?shù)組。這將允許我們在不改變LookupListener接口的情況下傳遞其它信息。例如,我們可以在LookupEvent中同時(shí)包括查找的字串和結(jié)果。下面是LookupEvent類:

 
 
 
  1. publicclassLookupEvent{  
  2. StringsearchText;  
  3. String[]results;  
  4. publicLookupEvent(StringsearchText){  
  5. this.searchText=searchText;  
  6. }  
  7. publicLookupEvent(StringsearchText,  
  8. String[]results){  
  9. this.searchText=searchText;  
  10. this.results=results;  
  11. }  
  12. publicStringgetSearchText(){  
  13. returnsearchText;  
  14. }  
  15. publicString[]getResults(){  
  16. returnresults;  
  17. }  

注意LookupEvent類是不可變的。這是很重要的,因?yàn)槲覀儾⒉恢涝趥鬟f過程中誰將處理這些事件。除非我們創(chuàng)建事件的保護(hù)拷貝來傳遞給每一個(gè)監(jiān)聽者,我們需要把事件做成不可變的。如果不這樣,一個(gè)監(jiān)聽者可能會(huì)無意或者惡意地修訂事件對象,并破壞系統(tǒng)。
現(xiàn)在我們需要在LookupManager上調(diào)用lookupComplete()事件。我們首先要在LookupManager上添加一個(gè)LookupListener的集合:

 
 
 
  1. publicvoidaddLookupListener(LookupListenerlistener){  
  2. listeners.add(listener);  
  3. }  
  4. publicvoidremoveLookupListener(LookupListenerlistener){  
  5. listeners.remove(listener);  

當(dāng)動(dòng)作發(fā)生時(shí),我們需要調(diào)用監(jiān)聽者的代碼。在我們的例子中,我們將在查找返回時(shí)觸發(fā)一個(gè)lookupCompleted()事件。這意味著在監(jiān)聽者集合上迭代,并使用一個(gè)LookupEvent事件對象調(diào)用它們的lookupCompleted()方法。
我喜歡把這些代碼析取到一個(gè)獨(dú)立的方法fire[event-method-name] ,其中構(gòu)造一個(gè)事件對象,在監(jiān)聽器集合上迭代,并調(diào)用每一個(gè)監(jiān)聽器上的適當(dāng)?shù)姆椒?。這有助于隔離主要邏輯代碼和調(diào)用監(jiān)聽器的代碼。下面是我們的fireLookupCompleted方法:

 
 
 
  1. privatevoidfireLookupCompleted(StringsearchText,  
  2. String[]results){  
  3. LookupEventevent=  
  4. newLookupEvent(searchText,results);  
  5. Iteratoriter=  
  6. newArrayList(listeners).iterator();  
  7. while(iter.hasNext()){  
  8. LookupListenerlistener=  
  9. (LookupListener)iter.next();  
  10. listener.lookupCompleted(event);  
  11. }  

我們知道這將在非Swing線程中調(diào)用,因?yàn)樵撌录侵苯釉贚ookupManager中觸發(fā)的,這將不是在Swing線程中執(zhí)行。因?yàn)樗械拇a功能上都是異步的(我們不必等待監(jiān)聽器方法允許結(jié)束后才調(diào)用其它代碼),我們可以通過SwingUtilities.invokeLater()將這些代碼改道到Swing線程。下面是新的方法,傳入一個(gè)匿名Runnable到SwingUtilities.invokeLater():

 
 
 
  1. publicvoidlookupCompleted(finalLookupEvente){  
  2. //noticethethreading  
  3. SwingUtilities.invokeLater(  
  4. newRunnable(){  
  5. publicvoidrun(){  
  6. outputTA.setText("");  
  7. Strin 

新聞標(biāo)題:淺析Swing線程中的LookupEvent
分享地址:http://www.dlmjj.cn/article/cdesoio.html