自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

介紹輕量級(jí)Swing組件

開(kāi)發(fā) 后端
本文介紹輕量級(jí)Swing組件,Swing的GUI總是由頂層容器組件和輕量級(jí)Swing組件組合建立,頂層容器和其他組件區(qū)別主要在于頂層容器沒(méi)有自身的paint邏輯。

JFrame被構(gòu)造的時(shí)候就會(huì)創(chuàng)建root pane, layered pane,content pane, glass pane等,這些沒(méi)有對(duì)等體的輕量級(jí)Swing組件在構(gòu)造時(shí)都將repaint。雖然在創(chuàng)建windows對(duì)等窗口之前這些Swing組件就已經(jīng)在要求繪制,但是RepaintManager能夠協(xié)調(diào)好這個(gè)步調(diào)(具體即是當(dāng)收到repaint請(qǐng)求時(shí)要判斷情況,像這時(shí)的請(qǐng)求因?yàn)轫攲尤萜鬟€沒(méi)有繪制則不會(huì)記錄到重畫(huà)區(qū))。所以最終效果就是在peer.pshow的時(shí)候只能看到一個(gè)空窗口,隨后底層消息到來(lái)后通過(guò)paint回調(diào)畫(huà)這些子組件,***hello world才顯示出來(lái)。如果眼神好,能夠看出這有一個(gè)“閃爍”。

這是一個(gè)最簡(jiǎn)單的Swing應(yīng)用程序的基本運(yùn)行機(jī)制分析,下面再具體分析。
Swing的GUI總是由頂層容器組件和輕量級(jí)Swing組件組合建立,頂層容器和其他組件區(qū)別主要在于頂層容器沒(méi)有自身的paint邏輯。
所有頂層容器都是通過(guò)使用底層系統(tǒng)API來(lái)繪制對(duì)等體的方式進(jìn)行paint,自身沒(méi)有java2d的paint邏輯實(shí)現(xiàn),對(duì)等體畫(huà)成什么樣頂層容器就是什么樣,它只是可以控制對(duì)等體的一些可配顯示屬性。所以效果就是比如在windows平臺(tái)上畫(huà)一個(gè)jframe,除在桌面上顯示一個(gè)窗口還會(huì)在任務(wù)欄上顯示一個(gè)條目。Swing的 4個(gè)頂層容器都是在addNotify時(shí)才會(huì)getToolkit().createPeer(this)(Frame/Dialog/Window), 而addNotify并不是在構(gòu)造時(shí)被調(diào)用,而是在pack/show或setvisible(這3個(gè)所謂的realized具現(xiàn)化方法)時(shí)被調(diào)用。創(chuàng)建了對(duì)等體peer后還要通過(guò)peer.pShow(show/setVisible(true)調(diào)用)調(diào)用才會(huì)要求底層系統(tǒng)進(jìn)行顯示(所以只有pack是不會(huì)顯示窗口的)。在顯示窗口后底層消息隊(duì)列得到通知,此后隨著窗口被最小化后恢復(fù)或被遮蓋后恢復(fù)等系統(tǒng)操作后同樣能從底層消息得到通知,這時(shí)的監(jiān)聽(tīng)處理將有選擇地通知給RepaintManager一個(gè)重畫(huà)請(qǐng)求進(jìn)行窗口內(nèi)容-子組件重畫(huà)。

而輕量級(jí)Swing組件將繪制有關(guān)的職責(zé)都委托給了ui成員對(duì)象,ui對(duì)象使用JAVA2D API 進(jìn)行繪制,paint成什么樣那就是這個(gè)組件的樣子。具體就是在構(gòu)造的時(shí)候即要 updateUI{setUI(UIManger.getUI(this))}。UIManger會(huì)根據(jù)當(dāng)前L&F的選擇,根據(jù) this.uiClassID來(lái)得到ui成員類(lèi)并建立實(shí)例,以后的paint回調(diào)等都推托給ui成員類(lèi)paint,這也算是一種策略模式。Setui的過(guò)程中除了保存這個(gè)ui實(shí)例外,將repaint來(lái)通知RepaintManager進(jìn)行paint回調(diào)完成組件繪制。輕量級(jí)Swing組件在addNotify時(shí)也會(huì)去創(chuàng)建對(duì)等體getToolkit().createPeer(this)( LightWeightPeer),但這個(gè)peer的實(shí)現(xiàn)(NullComponentPeer)是個(gè)空殼子,只是作為一個(gè)輕量級(jí)組件的標(biāo)記,以后的很多事件處理等都要判斷peer是否instance of LightWeightPeer從而能夠進(jìn)行不同處理。

同樣的Addnotify也不是在構(gòu)造時(shí)被調(diào)用,而是在被加入container時(shí)被調(diào)用。
注意:構(gòu)造方法本身就是狀態(tài)模式的***狀態(tài),所以GUI組件的構(gòu)造方法里就應(yīng)該要努力完成自身的繪制來(lái)符合自己的地位。輕量級(jí)組件就是按這個(gè)意義在構(gòu)造方法里去通知repaintmanager進(jìn)行自身繪制的,但是頂層容器卻將真正的繪制意圖createPeer延遲到了具現(xiàn)方法里。這是因?yàn)槭紫纫粋€(gè)合乎思維的表達(dá)邏輯是先有容器,再將子組件向容器里添加,所以最頂層容器總是先行構(gòu)造出來(lái),然后再被一層層地追加輕量級(jí)子組件。如果最頂層容器在構(gòu)造時(shí)就去具現(xiàn),則就要求后續(xù)的構(gòu)造都應(yīng)該在EDT中進(jìn)行,而且每次add子組件都要導(dǎo)致revalidate;但若將最頂層容器的繪制分離延遲到具現(xiàn)方法里,則可以表達(dá)是在容器里盛滿了要顯示的子組件后再一股腦具現(xiàn)繪制出來(lái)的概念,類(lèi)似于在進(jìn)行一次web頁(yè)面的完整加載,然后注意在具現(xiàn)方法執(zhí)行后如果要操作組件都在EDT中進(jìn)行即可,而且頂層容器提供一個(gè)特有的 pack方法,用來(lái)一次性對(duì)所有子組件驗(yàn)證大小位置進(jìn)行重布局,pack之后再show,這樣的一次性計(jì)算展現(xiàn)是最有效率的。

頂層容器和輕量級(jí)組件就是這樣誕生并繪制的,在此后的生命周期里,都將按事件監(jiān)聽(tīng)機(jī)制完成GUI隨需而變,無(wú)論是系統(tǒng)事件,還是因?yàn)閞epaint調(diào)用主動(dòng)post事件,事件到來(lái)后再在EDT中執(zhí)行監(jiān)聽(tīng)器里的paint繪制。Swing已經(jīng)提供的頂層容器和輕量級(jí)組件因各自的定義已經(jīng)注冊(cè)了各自的paint監(jiān)聽(tīng),開(kāi)發(fā)人員可以再行維護(hù)或按此模式開(kāi)發(fā)新組件從而滿足應(yīng)用的需要。比如,jbutton默認(rèn)有mousepress listener,在mousepress事件到來(lái)后,監(jiān)聽(tīng)響應(yīng)中會(huì)設(shè)置鼠標(biāo)顏色加深來(lái)表示按下,然后再調(diào)用repaint要求重畫(huà),隨后在EDT中執(zhí)行 jbutton的paint回調(diào),此時(shí)按深顏色繪制,于是一個(gè)被按下的效果就出來(lái)了。
下面在具體分析各類(lèi)事件的處理。

對(duì)于頂層容器的受底層事件消息的觸發(fā),當(dāng)?shù)玫降耐ㄖ且驗(yàn)閑xpose暴露隱藏區(qū)(暴露被遮蔽的部分或恢復(fù)最小化或***次繪制等)時(shí),處理過(guò)程會(huì)涉及到雙緩存的處理,即如果可能,直接使用緩存中的舊圖像信息進(jìn)行覆蓋而不再重新繪制。

所謂雙緩存機(jī)制是將一整片的顯示內(nèi)容暫時(shí)寫(xiě)入一張內(nèi)存空間里,然后一次性內(nèi)存拷入顯示區(qū)來(lái)進(jìn)行顯示,這樣處理是因?yàn)槿绻苯訉?xiě)入顯示區(qū),隨著顯示區(qū)被該寫(xiě)入線程逐漸寫(xiě)入,可能經(jīng)歷多次屏幕刷新,導(dǎo)致每次刷新都形成過(guò)程圖像,給人眼造成閃爍感覺(jué);同時(shí)一個(gè)副收益就是可以針對(duì)每個(gè)窗口都做緩存待用(而不僅僅是針對(duì)一個(gè)屏幕雙緩存),當(dāng)窗口被遮擋的部分重現(xiàn)時(shí)直接拷貝緩存來(lái)覆蓋,不用再執(zhí)行繪畫(huà)邏輯,提高了效率。

現(xiàn)在的OS一般都提供雙緩存機(jī)制支持,如果底層系統(tǒng)自身支持以每個(gè)窗口為單位做雙緩存,則該expose消息將被本地處理,不需要通知進(jìn)行子組件的繪制;如果底層不支持,則該消息會(huì)到達(dá)wcomponetpeer.handleexpose中進(jìn)行回調(diào)處理,此時(shí)Swing機(jī)制下有一個(gè)參數(shù)控制的雙緩存機(jī)制可以提供。這里的參數(shù)控制需要從RepaintManager的構(gòu)造過(guò)程說(shuō)起。

首先RepaintManager可以通過(guò)static setCurrentManager(SomeCurrentManager)來(lái)進(jìn)行全局指定。默認(rèn)情況使用 currentRepaintManager(){new RepaintManager(BUFFER_STRATEGY_TYPE)}得到一個(gè)延遲創(chuàng)建的單例。RepaintManager有一段靜態(tài)類(lèi)初始化過(guò)程,涉及到雙緩存設(shè)置:

  1. static{  
  2. nativeDoubleBuffering="true".equals(AccessController.doPrivileged(  
  3. newGetPropertyAction("awt.nativeDoubleBuffering")));//JVM的啟動(dòng)參數(shù)控制,默認(rèn)false  
  4. Stringbs=AccessController.doPrivileged(  
  5. newGetPropertyAction("swing.bufferPerWindow"));//是否每窗口緩存。  
  6. if(headless){  
  7. BUFFER_STRATEGY_TYPE=BUFFER_STRATEGY_SPECIFIED_OFF;  
  8. }  
  9. elseif(bs==null){  
  10. BUFFER_STRATEGY_TYPE=BUFFER_STRATEGY_NOT_SPECIFIED;  
  11. }  
  12. elseif("true".equals(bs)){  
  13. BUFFER_STRATEGY_TYPE=BUFFER_STRATEGY_SPECIFIED_ON;  
  14. }  
  15. else{  
  16. BUFFER_STRATEGY_TYPE=BUFFER_STRATEGY_SPECIFIED_OFF;  
  17. }  
  18. }  
  19. privateRepaintManager(shortbufferStrategyType){  
  20. //Ifnativedoublebufferingisbeingused,doNOTuse  
  21. //Swingdoublebuffering.  
  22. doubleBufferingEnabled=!nativeDoubleBuffering;  
  23.  
  24. this.bufferStrategyType=bufferStrategyType;  
  25.  
  26. }  
  27. publicvoidsetDoubleBufferingEnabled(booleanaFlag){  
  28. doubleBufferingEnabled=aFlag;  
  29.  
  30. doubleBufferingEnabled(開(kāi)啟雙緩存),nativeDoubleBuffering(利用本地雙緩存機(jī)制)
    ,bufferStrategyType(每窗口雙緩存策略)  
  31. 這幾個(gè)參數(shù)將影響到RepaintManager的成員對(duì)象paintManager的選擇,也算是一個(gè)策略模式
    ,該paintManager是負(fù)責(zé)繪制的核心類(lèi)。  
  32. privatesynchronizedPaintManagergetPaintManager(){  
  33. if(paintManager==null){  
  34. PaintManagerpaintManager=null;  
  35. if(doubleBufferingEnabled&&!nativeDoubleBuffering){  
  36. switch(bufferStrategyType){  
  37. caseBUFFER_STRATEGY_NOT_SPECIFIED:  
  38. if(((SunToolkit)Toolkit.getDefaultToolkit()).  
  39. useBufferPerWindow()){//windows下是否禁用vistadwm,
    在沒(méi)有聲明bufferPerWindow的情況下由windows系統(tǒng)特性確定paintmanager。  
  40. paintManager=newBufferStrategyPaintManager();  
  41. }  
  42. break;  
  43. caseBUFFER_STRATEGY_SPECIFIED_ON:  
  44. paintManager=newBufferStrategyPaintManager();  
  45. break;  
  46. default:  
  47. break;  
  48. }  
  49. }  
  50. //nullcasehandledinsetPaintManager  
  51. setPaintManager(paintManager);  
  52. }  
  53. returnpaintManager;  
  54. }  
  55. voidsetPaintManager(PaintManagerpaintManager){  
  56. if(paintManager==null){  
  57. paintManager=newPaintManager();  
  58. }  
  59.  

以上是介紹輕量級(jí)Swing組件。

【編輯推薦】

  1. 概述Swing核心組件
  2. 淺談NetBeans開(kāi)發(fā)Swing
  3. Swing模式就是走RepaintManager的方式
  4. 淺析Swing Image的轉(zhuǎn)換
  5. 介紹AWT和Swing組件
責(zé)任編輯:佚名 來(lái)源: IT168
相關(guān)推薦

2009-07-14 18:05:28

輕量級(jí)Swing組件

2009-07-10 18:06:59

JTree Swing

2009-07-17 11:13:46

AWT和SwingSwing組件

2023-02-03 15:21:52

2023-09-27 00:12:23

2013-02-20 14:54:03

C#.NETNDatabase

2023-08-09 08:01:38

場(chǎng)景Redis接口

2009-09-11 08:26:49

Linux系統(tǒng)CRUX 2.6Linux

2016-10-14 16:35:39

2009-07-10 13:36:32

Swing容器

2010-09-09 13:12:29

XML DOM

2023-12-22 14:07:00

Go輕量級(jí)Goroutines

2022-08-10 12:21:07

PythonWebBottle

2009-06-23 08:56:55

Linux桌面搜索

2020-11-11 12:13:59

JS

2022-07-15 16:39:19

PythonWhoosh工具

2009-07-17 12:54:13

2009-07-10 15:41:27

Swing AWT

2009-07-15 10:37:28

Swing外觀

2022-03-14 08:02:08

輕量級(jí)動(dòng)態(tài)線程池
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)