新聞中心
昨晚回去后還是覺(jué)得Component對(duì)象本身說(shuō)的太簡(jiǎn)單,想來(lái)想去,覺(jué)得內(nèi)容實(shí)在是太多,有必要補(bǔ)充兩個(gè)續(xù)文說(shuō)明Component的其它概念。今天介紹Swing組件paint方法的處理流程,這個(gè)流程能使我們理解許多Swing機(jī)制。

成都創(chuàng)新互聯(lián)公司于2013年開(kāi)始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站制作、成都網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元萊蕪做網(wǎng)站,已為上家服務(wù),為萊蕪各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220
Swing組件的paint方法是內(nèi)部接口方法,一般用戶不要直接調(diào)用這個(gè)方法,它總是在事件調(diào)度線程中調(diào)用。一般說(shuō)來(lái)除了系統(tǒng)刷新事件觸發(fā)這個(gè)方法, Component的repaint也觸發(fā)這個(gè)方法的調(diào)用。repaint方法常用于當(dāng)組件狀態(tài)發(fā)生變化時(shí)刷新界面使用。repaint方法是Swing 中少數(shù)幾個(gè)線程安全的方法,可以在任何線程中調(diào)用它。它的原理是往事件隊(duì)列中post一個(gè)PAINT事件。由于事件隊(duì)列的事件是被事件調(diào)度線程同步執(zhí)行的,所以這個(gè)方法總是線程安全的。事件調(diào)度線程從PAINT事件中獲取事件源組件,從系統(tǒng)申請(qǐng)到圖形設(shè)備資源后,調(diào)用該組件的update方法。 update是AWT時(shí)代遺留下來(lái)的產(chǎn)物,本意是AWT組件畫好組件背景后,再調(diào)用paint方法畫出組件的前景。Swing出現(xiàn)后這個(gè)方法就被棄用了,所有邏輯都轉(zhuǎn)到paint方法里。Update只是簡(jiǎn)單地調(diào)用paint方法來(lái)完成組件的渲染。老的Java教材上經(jīng)??梢钥吹?,所謂repaint調(diào)度 update方法,update接著調(diào)用paint方法,自定義組件需要重載paint方法等話語(yǔ),就是因?yàn)檫@個(gè)歷史造成的。
現(xiàn)在JComponent的實(shí)現(xiàn)已經(jīng)把paint方法改造成可以嵌套多重機(jī)制地方,這些機(jī)制包括層次渲染、邊框、透明背景、雙緩沖以及皮膚等。這些機(jī)制分別實(shí)現(xiàn)不同目的的組件提供了方便。
圖形用戶界面的組件按照其在組件樹(shù)上的角色可以分為容器組件和葉組件。Swing模型把葉組件當(dāng)作是特殊、沒(méi)有子組件的容器組件,只是JComponent繼承Container類,所有Swing組件繼承JComponent的原因。
JComponent在paint方法中首先根據(jù)組件是否需要使用雙緩沖,封裝好圖形設(shè)備對(duì)象,然后經(jīng)過(guò)一番處理后調(diào)用paintComponent方法畫出自身,然后調(diào)用paintBorder畫出邊框,最后調(diào)用paintChildren來(lái)完成子組件的渲染。
paintComponent意思是畫出組件自身,不包括子組件。因此前一文章中的MyButton可以通過(guò)覆蓋paintComponent方法來(lái)完成 MyButton的重畫。在JComponent實(shí)現(xiàn)中,JDK 6的paintComponent的代碼為:
- protectedvoidpaintComponent(Graphicsg){
- if(ui!=null){
- GraphicsscratchGraphics=(g==null)?null:g.create();
- try{
- ui.update(scratchGraphics,this);
- }
- finally{
- scratchGraphics.dispose();
- }
- }
- }
可以看出,背景透明機(jī)制在這兒實(shí)現(xiàn)。首先UI Delegate對(duì)象判斷Component是否背景透明的,如果不是透明的,則使用背景色填充整個(gè)Component區(qū)域,然后調(diào)用paint(g, c)來(lái)完成組件在這種LookAndFeel種的渲染。了解了這些后,我們幾乎就明白了Swing如何實(shí)現(xiàn)背景透明和如何切換皮膚。由于后面的文章還會(huì)對(duì) UI Delegate和皮膚機(jī)制詳細(xì)描述,這兒就到此為止。
目前還不要求實(shí)現(xiàn)皮膚,在這種情況下只需要重載paintComponent方法就行了,如果需要背景透明機(jī)制,可以模仿上面代碼,MyButton的paintComponent可以這樣寫:
- publicvoidpaintComponent(Graphicsg){
- if(isOpaque()){
- g.setColor(getBackground());
- g.fillRect(0,0,getWidth(),getHeight());
- }
- if(pressed){//按鈕按下去了
- //畫出按下的樣子
- }else{
- //畫出抬起的樣子
- }
- }
paintChildren完成容器類組件的子組件的渲染。JDK缺省的實(shí)現(xiàn)是調(diào)用各個(gè)自組件的paint方法。一般來(lái)說(shuō)不需要重載這個(gè)方法。如果想改變諸如組件Z-order遮擋順序,可以覆蓋這個(gè)方法,從相反順序調(diào)用組件的paint方法。
到這兒我們對(duì)Swing的結(jié)構(gòu)有了更深化的理解,UI Delegate機(jī)制也已經(jīng)初露倪端。還有幾個(gè)重要Swing Component概念或者機(jī)制沒(méi)有講,明天的續(xù)文再對(duì)它們做出說(shuō)明。
標(biāo)題名稱:Swing組件的paint方法的處理流程
標(biāo)題網(wǎng)址:http://www.5511xx.com/article/dhpijph.html


咨詢
建站咨詢
