日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺談EventQueue in Swing

最近在看多線程的東西,EventQueue in Swing負責(zé)所有AWTEvent(以及其子類)的分發(fā),以后如果要定義自己的ProgressBar可能會用到,先記下來。

創(chuàng)新互聯(lián)一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個客戶多一個朋友!為您提供成都做網(wǎng)站、網(wǎng)站設(shè)計、成都網(wǎng)頁設(shè)計、小程序定制開發(fā)、成都網(wǎng)站開發(fā)、成都網(wǎng)站制作、成都軟件開發(fā)、成都app軟件開發(fā)公司是成都本地專業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計公司,等你一起來見證!

EventQueue in Swing簡單工作原理

簡單來講,在EventQueue中有一個dispatchThread,這是一個線程類,負責(zé)事件的分發(fā),當(dāng)Queue中有事件的時候,它會摘取前面的事件并分發(fā)給相應(yīng)的對象進行處理,等處理完之后再獲取下一個,當(dāng)Queue中沒有事件的時候,線程等待。

當(dāng)有事件觸發(fā)時,系統(tǒng)會調(diào)用EventQueue的push方法將AWTEvent添加到EventQueue的最后,同時喚醒dispatchThread。

為什么界面會死掉

所以可以看到,Swing的事件分發(fā)實際上是同步的,并且都是在dispatchThread這個線程中處理的,也就是說是一個事件一個事件處理的,如果有某一個事件處理的時間非常長的時侯,其他事件就會被堵塞在那里,從現(xiàn)象上看得話,就是界面會死掉,如果界面被其他窗口覆蓋之后再回到前面的時侯,會變成一片灰色,這是因為PaintEvent被堵塞而不能被分發(fā)出去的緣故。

為什么Modal Dialog(Frame)彈出的時候界面不會死

當(dāng)在處理事件的時侯如果彈出一個Modal Dialog,那么處理方法會停在那里并等待Modal Dialog銷毀,這個時候按照上面的分析,dispatchThread也會停在那里,這樣的話其他事件也不會被分發(fā),那么界面也應(yīng)該會死掉才對。實際上在等待Modal Dialog銷毀的過程中,如果能夠保證事件可以順利地分發(fā)出去的話,界面當(dāng)然就不會死。先來看這個例子。

 
 
 
  1. packageeventqueue;  
  2.  
  3. importjava.awt.AWTEvent;  
  4. importjava.awt.ActiveEvent;  
  5. importjava.awt.Component;  
  6. importjava.awt.EventQueue;  
  7. importjava.awt.MenuComponent;  
  8. importjava.awt.event.ActionEvent;  
  9. importjava.awt.event.ActionListener;  
  10.  
  11. importjavax.swing.JButton;  
  12. importjavax.swing.JDialog;  
  13.  
  14. publicclassTestEvent{  
  15. publicstaticvoidmain(String[]args){  
  16. finalJDialogdlg=newJDialog();  
  17. dlg.setTitle("TestEventQueue");  
  18. JButtonbtn=newJButton("Test");  
  19. dlg.getContentPane().add(btn);  
  20. btn.addActionListener(newActionListener(){  
  21. publicvoidactionPerformed(ActionEvente){  
  22. longnow=System.currentTimeMillis();  
  23. EventQueuetheQueue=dlg.getToolkit().getSystemEventQueue();  
  24. System.out.println("atleast5000millis");  
  25. while(System.currentTimeMillis()-now<5000l){  
  26. try{  
  27. //ThisisessentiallythebodyofEventDispatchThread  
  28. AWTEventevent=theQueue.getNextEvent();  
  29. Objectsrc=event.getSource();  
  30. if(eventinstanceofActiveEvent){  
  31. ((ActiveEvent)event).dispatch();  
  32. }elseif(srcinstanceofComponent){  
  33. ((Component)src).dispatchEvent(event);  
  34. }elseif(srcinstanceofMenuComponent){  
  35. ((MenuComponent)src).dispatchEvent(event);  
  36. }  
  37. }catch(Exceptionex){  
  38. ex.printStackTrace();  
  39. }  
  40. }  
  41. System.out.println("end");  
  42. }  
  43. });  
  44. dlg.pack();  
  45. dlg.show();  
  46. }  
  47. }  
  48.  

在上面Swing的例子中,當(dāng)Button的Action被觸發(fā),actionPerformed方法執(zhí)行的時候,會首先幫助EventQueue分發(fā)事件,直到最少5秒之后返回,這時可以看到這個事件處理方法至少執(zhí)行了5秒鐘,但是在這個過程中Dialog仍然可以正常工作,只是因為在這5秒之中并非是Sleep,而是在幫助EventQueue分發(fā)事件,如果代碼改成
Thread.sleep(5000);
的話,界面將會死掉。

所以在Modal Dialog彈出的時候,實際上只要在show方法中能夠?qū)崿F(xiàn)類似上面的代碼,保證事件可以正常的分發(fā)(同時截獲父窗口的一些事件,過濾掉一些觸發(fā)Action的事件),那么父窗口的界面就不會死掉。

當(dāng)事件處理方法很長時間才能做完該怎么辦

當(dāng)事件處理方法需要很長時間才能執(zhí)行完的話,如果需要保證界面不死的話,還是只能用多線程,雖然上面的方法實現(xiàn)了事件處理的時候界面不死,但是這和一般的事件處理是有不同的,上面的方法實際上在處理的時候什么都沒有做,而我們一般需要有自己的操作(比如訪問數(shù)據(jù)庫,訪問網(wǎng)絡(luò),讀寫操作等需要很長時間才能處理完的工作),不可能做到一邊在操作一邊處理Event分發(fā),這個時候只有新建一個線程才是正道。

不過關(guān)于很多EventQueue in Swing和EventDispatchThread的方法都被封裝在其實現(xiàn)里面,對外不可視,導(dǎo)致不可能對其進行一些修改,有點不爽。另外在EventQueue中的AWTEvent一般都是給最上層對象的,比如最上層的JDialog或者JFrame,然后由JDialog或者JFrame分發(fā)給其他的Component,不過我不知道怎么可以從AWTEvent事件找到真正的擁有者,這一點比較郁悶

【編輯推薦】

  1. 在表格中Swing增加列表框
  2. 淺談Swing控件JList
  3. 概述Swing組件與外部線程
  4. Java Swing做什么好
  5. Swing文件選擇器的制作

當(dāng)前標題:淺談EventQueue in Swing
網(wǎng)站地址:http://www.5511xx.com/article/cosodis.html