999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

Java GUI中的paint方法疑難解析

2018-05-14 07:09:58張亞利吳彥國
科技風 2018年15期

張亞利 吳彥國

摘要:在進行Java GUI編程時,程序利用paint(Graphics g)方法來實現組件的繪制;然而Java的繪圖機制是怎樣的,paint方法又是何時調用、如何調用,且每次調用時paint方法的執行次數是怎樣的?輕量級和重量級組件調用paint有哪些區別等,本文作者將針對這些問題,用案例分析的方法來一一解答。

關鍵詞:繪圖機制;paint;調用

學過Java程序設計語言的朋友都知道,在學習Java GUI編程時,我們都知道paint方法是用來繪制圖形的。有了paint方法,我們可以在Java中繪制各種漂亮的組件,或開發漂亮炫酷的游戲。但是paint是如何調用的?程序啟動時,paint方法執行了一次還是多次,原理是什么?另外Swing組件和AWT組件對super.paint方法是如何相應的,組件在處理動畫時,對KeyListner又是如何響應的呢?關于這些細節性的問題,許多初學者總是模棱兩可。筆者經過查找資料,并寫程序進行驗證,得出一些結果,以供分享。

問題1:Java的繪圖機制是怎樣的?

AWT是使用回調機制來處理繪畫的,并且這種機制對輕量級和重量級組件相同。也就是說我們需要把渲染組件的代碼寫在一個可覆蓋的特殊的方法中,這個方法是public void paint(Graphics g);其中 Graphics是圖形上下文對象,用來完成具體的繪制工作。paint方法由AWT框架調用或者由程序自身通過repaint方法來調用。

問題2:畫圖時,paint是何時調用,如何調用,調用幾次的問題。

Java繪圖時,用到的paint方法繼承自AWT中的Component方法,該方法在對象加載時自動調用,用來繪制該組件內部的所有圖形圖像。使用repaint()方法,可以再次調用paint方法,實現組件的重繪。但是paint方法是什么時候開始執行,執行了幾次呢?下面我們用例子,來加以分析。

public class Test extends Applet//引入包的代碼省略

{Image img = null;int t =0;

public void init(){System.out.print("初始化====");

img = getImage(getCodeBase(),"1.jpg");}

public void paint(Graphics g)

{t++;System.out.print("我是paint===="+t+"");

g.fillRect(50,50,80,80);//代碼段1,繪制矩形

// g.drawImage(img,50,50,this); //代碼段2,繪制圖形}}

執行代碼段1的結果:

初始化====我是paint====1

執行代碼段2的結果:

初始化====我是paint====1我是paint====2……我是paint====47

從上面結果可以發現,啟動瀏覽器時,系統自動調用init()方法進行程序初始化,接著系統自動找到paint()方法對圖像進行繪制。而且paint()方法調用的次數,跟繪制的內容有關,圖形簡單時,可能執行一次,圖像復雜時,可能會自動調用很多次,直到圖形圖像完全繪制成功。另外還有當組件大小發生改變,或組件有壞點(damage)需要被修復時,系統都會自發地調用repaint方法,進行組件的重繪。

問題3:Java程序繪圖時,JPanel和Panel對super.paint()的響應問題。

Java通過調用paint()方法來繪制組件,但是 AWT框架中輕量級組件與重量級組件實現代碼還是有區別的。

輕量級組件的繪制依賴與包含關系階層中的重量級祖先組件,當這個祖先組件被通知繪制時,它將把繪制請求轉化為繪制自身上任何可見的子孫組件,這個方法是由java.awt.Container中的 paint() 方法來完成的,因此任何Container的子類,在覆蓋paint方法時一定要記得調用super.paint()來保證,它上面的輕量級子孫組件都被繪制到了。代碼可以這樣來完成:

public class MyContainer extends Container {

public void paint(Graphics g) { // 先繪制自身內容, 然后確保輕量級子組件被繪制

super.paint(g);}}

下面我們將通過案例,來觀察:

class myPanel extends JPanel implements KeyListener //重要代碼:繼承JPanel/Panel

{int x=50;public myPanel(){addKeyListener(this);} //為面板增加鍵盤監聽器

public void paint(Graphics g){super.paint(g);//重要代碼段:super.paint

g.setColor(Color.orange); g.fillRect(x, 50, 60, 60);}//設置畫筆顏色,填充矩形

public void keyPressed(KeyEvent e){x=x+10;repaint();//釋放鍵盤,矩形向右移動10像素;}

public void keyTyped(KeyEvent e){}

public void keyReleased(KeyEvent e){}}

創建myPanel對象p,設置背景色為青色,同時在面板p上添加標簽“測試super.paint()”,程序將出現四種情況,對應3種效果。

(1)面板繼承JPanel,且paint方法中調用super.paint(),所得結果如圖2。

(2)面板繼承JPanel,且paint方法中沒有調用super.paint(),所得結果如圖1。

(3)面板繼承Panel,且paint方法中沒有調用super.paint(),所得結果如圖3。

(4)面板繼承Panel,且paint方法中調用super.paint(),所得結果如圖2。

問題4:處理動畫時,JPanel和JApplet等Swing組件對KeyListner無響應的問題。

為面板增加鍵盤監聽器KeyListner,若面板繼承java.awt.Panel,那么當程序運行時,每敲擊一次鍵盤,上述案例中的矩形方塊開始向右移動10個像素的距離;但是若面板繼承javax.swing.JPanel,敲擊鍵盤,則無任何相應動作。這又是什么原因引起的呢?

經過實驗分析,筆者發現JPanel等Swing組件在渲染完成后,無法獲取focus,所以我們只需要上層容器setvisible(true)之前,先設置 p.requestFocus();為面板對象獲取焦點即可。

以上分析,希望對愛好Java GUI編程的學習者提供幫助。

主站蜘蛛池模板: аv天堂最新中文在线| 一区二区三区四区在线| 国产肉感大码AV无码| 一本一本大道香蕉久在线播放| 99热这里只有精品在线观看| 在线观看国产网址你懂的| 九九热精品免费视频| 亚洲91在线精品| 尤物国产在线| 在线免费观看a视频| 亚洲人成网站色7777| 国产精品开放后亚洲| 国产成人无码久久久久毛片| 欧美激情首页| 孕妇高潮太爽了在线观看免费| 青草视频久久| 亚洲人视频在线观看| 亚洲天堂777| 综合亚洲网| AV无码国产在线看岛国岛| 欧美精品影院| 亚洲性色永久网址| 国产成人av一区二区三区| 中文字幕2区| 亚洲天堂网视频| 精品久久国产综合精麻豆| 97免费在线观看视频| 玩两个丰满老熟女久久网| 国产成人成人一区二区| 国产精品香蕉在线观看不卡| 无码视频国产精品一区二区| 中文字幕人妻无码系列第三区| 国产精品区网红主播在线观看| 久久亚洲国产视频| 久久综合色播五月男人的天堂| 成人国产免费| 1024你懂的国产精品| 伊人中文网| 欧美福利在线观看| 亚洲首页在线观看| 99精品影院| 国产亚洲精品资源在线26u| 农村乱人伦一区二区| 免费毛片a| 色婷婷亚洲综合五月| 亚洲三级影院| 制服丝袜一区二区三区在线| 99国产精品国产高清一区二区| 久久人体视频| 草逼视频国产| 成人免费午间影院在线观看| 欧美日韩专区| 国产三级毛片| 久久不卡精品| 国产欧美视频综合二区| 国产麻豆91网在线看| 国产青榴视频| 欧美精品亚洲精品日韩专区| 波多野结衣第一页| 欧美视频在线第一页| 国产永久在线视频| 欧美.成人.综合在线| 国产你懂得| 美女内射视频WWW网站午夜| 丁香婷婷久久| 亚洲黄色成人| 亚洲国产成人麻豆精品| 天堂av综合网| 久久久久久午夜精品| 99re在线视频观看| 久久婷婷色综合老司机| 精品夜恋影院亚洲欧洲| av大片在线无码免费| 亚洲精品制服丝袜二区| 中文字幕久久亚洲一区| 一本大道AV人久久综合| 日本精品影院| 久青草国产高清在线视频| 天天色天天综合| 午夜精品区| 波多野结衣在线se| 色首页AV在线|