Java中的圖形界面重繪方式
Java圖形界面重繪方式
在我們編寫圖形界面程序的過程中,我們就會發(fā)現(xiàn),當(dāng)我們將窗體拉伸,縮?。ɑ蛘咦畲蠡钚』┑臅r候,之前在窗體上畫的圖形會消失了。
這是為什么呢?
1)原來,窗體包括其他的組件都是計算機(jī)繪制出來,我們一旦使得窗體發(fā)生改變,之前的一切都得重新繪制。但是,對于組件等有既定的重繪方法,對于我們所畫的圖形卻沒有重繪的方法。
2)也可以這樣解釋: 我們繪制圖形的數(shù)據(jù)都存儲在內(nèi)存中,而整個窗體都是調(diào)用系統(tǒng)底層的繪圖方法來繪制出來的。在創(chuàng)建窗體時我們已經(jīng)定義了窗體的大小,如果我們再次改變窗體大小的時候,原來的窗體就不滿足顯示的需求。這時候就會將窗體上所有的組件再重新繪制一次。調(diào)用了paint方法,這個方法是定義在JFrame和JPanel中都有的。
對于這樣的情況,我們只需要去重寫paint方法即可。 但是,這里有最為重要的一點,就是該類必須繼承JFrame類或者JPanel類,不然不可以重寫paint()?。?!
同時,我們需要注意一點還有:
- 數(shù)據(jù)的存儲方式及獲取方式,因為在程序運(yùn)行中 addActionListener() 方法只會調(diào)用一次,事件處理方法會多次出發(fā)。
- 所以如何將數(shù)據(jù)存儲下來并接著在paint方法中使用是我們需要去考慮的。
例如,我們可以先建立一個Shape類來記錄圖形信息,即坐標(biāo),類型等。
創(chuàng)建的Shape類
代碼如下:
package com.yf1014; import java.awt.Color; import java.awt.Graphics; /** * 圖形類 * @author yf * */ //Shape的主要功能:是記錄圖形信息,即坐標(biāo),類型等,然后根據(jù)所記錄的圖形信息來還原圖像的。 public class Shape { //屬性 public int x1,y1,x2,y2; public String name; //方法分為構(gòu)造方法和普通方法 //構(gòu)造方法 格式:public 類名(參數(shù)類型 參數(shù)名,,){} //普通方法 格式:public void 類名(參數(shù)類型 參數(shù)名,,){} //每個類都有一個默認(rèn)的無參構(gòu)造方法,當(dāng)自己定義構(gòu)造方法,默認(rèn)的構(gòu)造方法就會被替代 //作用:1.創(chuàng)建對象 2.初始化屬性 //this:表示本類對象 //此時該構(gòu)造方法的作用是: //當(dāng)創(chuàng)建對象時,將構(gòu)造方法內(nèi)傳進(jìn)來的參數(shù)賦給屬性,這樣我每創(chuàng)建一個新的對象時,該對象就擁有這些屬性了。 public Shape(int x1,int y1,int x2,int y2,String name){ this.x1 = x1;//當(dāng)參數(shù)名和屬性名相同時,使用this來使得參數(shù)賦值給屬性 this.y1 = y1; this.x2 = x2; this.y2 = y2; this.name = name; } //根據(jù)保存的數(shù)據(jù)還原圖形對象 public void drawShape(Graphics g){ if("直線".equals(name)){ g.drawLine(x1, y1, x2, y2); } else if("矩形".equals(name)) { g.drawRect(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1)); } else if("小熊".equals(name)) { //頭 Color headColor = new Color(224, 178, 142); g.setColor(headColor); g.fillRect(x1, y1, 110, 110); g.fillArc(x1, y1, 20, 20, 1, 2); //眼睛 g.setColor(Color.WHITE); g.fillOval(x1+20, y1+32, 18, 24); g.setColor(Color.WHITE); g.fillOval(x1+75, y1+32, 18, 24); //眼黑 g.setColor(Color.BLACK); g.fillOval(x1+23, y1+36, 10, 14); g.setColor(Color.BLACK); g.fillOval(x1+78, y1+36, 10, 14); //嘴巴 Color mouse = new Color(248, 246, 229); g.setColor(mouse); g.fillOval(x1+37, y1+57, 40, 30); //鼻子 g.setColor(Color.BLACK); g.fillOval(x1+53, y1+50, 9, 9); //左耳 g.setColor(Color.RED); g.fillOval(x1+3, y1+3, 22, 22); //右耳 g.setColor(Color.RED); g.fillOval(x1+84, y1+3, 22, 22); //Shape shape = new Shape(x1, y1, x2, y2, name); } } }
然后創(chuàng)建一個MyFrame類,該類的主要作用就是重寫paint方法。
首先,在該類中,利用Shape類創(chuàng)建一個數(shù)組shapeArray來保存對象(用于保存圖形信息,即坐標(biāo),類型等)。
MyFrame類
代碼如下:
package com.yf1014; import java.awt.Graphics; import javax.swing.JFrame; //MyFrame的主要功能是:是將保存在數(shù)組中的圖形對象信息進(jìn)行重繪,即重寫paint方法的,因為需要在畫布上操作,所以需要繼承JFrame類。 public class MyFrame extends JFrame { // 定義Shape數(shù)組,保存對象(用于保存圖形信息,即坐標(biāo),類型等) private Shape[] shapeArray; //利用普通方法,將傳進(jìn)來的數(shù)組類型shapeAraay賦給屬性值,也可以采用的構(gòu)造方法來進(jìn)行該操作,換言之,這兩種方法都可以來實現(xiàn)傳參數(shù)給屬性值 public void setShapeArray(Shape[] shapeArray){ this.shapeArray = shapeArray; } //重寫paint方法 public void paint(Graphics g) { super.paint(g);//先繼承父類的paint方法,然后再利用下述方法重寫paint方法 //遍歷setShapeArray數(shù)組,取出圖形對象 for(int i=0;i<shapeArray.length;i++){ Shape shape = shapeArray[i]; if(shape != null){ shape.drawShape(g); } } } }
接著,我們就要創(chuàng)建一個DrawMouse監(jiān)聽器類,實現(xiàn)事件監(jiān)聽功能。
代碼如下:
package com.yf1014; import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; //事件處理類 public class DrawMouse implements MouseListener, ActionListener { // 定義Graphics變量gr,用來保存?zhèn)鬟f過來的文本框?qū)ο? private Graphics gr; private int x1, y1, x2, y2; private String name; //定義Shape數(shù)組,保存對象(用于保存圖形信息,即坐標(biāo),類型等) Shape[] shapeArray = new Shape[100]; //操作數(shù)組的下標(biāo) int index = 0; //構(gòu)造方法,將傳進(jìn)來的參數(shù)g賦給屬性gr public DrawMouse(Graphics g){ gr = g; } // 定義set方法,初始化gr變量(即為普通方法,這個時候的功能是和上述的構(gòu)造方法的功能是相同的,然而當(dāng)我還需要傳入另一個參數(shù)時,則需要利用普通方法來實現(xiàn)) //在本文中,構(gòu)造方法DrawMouse和普通方法setGr可以任選其一即可。 public void setGr(Graphics g) { gr = g; } //接下這些東西就是監(jiān)聽器MouseListener和ActionListener的抽象方法的重寫。 public void actionPerformed(ActionEvent e) { //獲取按鈕上的字符串 name = e.getActionCommand(); System.out.println("name = "+name); } public void mouseClicked(MouseEvent e) { System.out.println("點擊"); if(e.getClickCount() == 2){ } } public void mousePressed(MouseEvent e) { System.out.println("按下"); x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { System.out.println("松開"); x2 = e.getX(); y2 = e.getY(); // 設(shè)置畫筆顏色 // gr.setColor(Color.BLUE); if("直線".equals(name)){ // 畫圖 gr.drawLine(x1, y1, x2, y2); //創(chuàng)建Shape對象,保存該圖形的數(shù)據(jù) Shape shape = new Shape(x1, y1, x2, y2, name); //保存shapeArray數(shù)組 shapeArray[index++] = shape; } else if("矩形".equals(name)){ // 矩形 gr.drawRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1)); //創(chuàng)建Shape對象,保存該圖形的數(shù)據(jù) Shape shape = new Shape(x1, y1, x2, y2, name); //保存shapeArray數(shù)組 shapeArray[index++] = shape; } else if("小熊".equals(name)) { //頭 Color headColor = new Color(224, 178, 142); gr.setColor(headColor); gr.fillRect(x1, y1, 110, 110); gr.fillArc(x1, y1, 20, 20, 1, 2); //眼睛 gr.setColor(Color.WHITE); gr.fillOval(x1+20, y1+32, 18, 24); gr.setColor(Color.WHITE); gr.fillOval(x1+75, y1+32, 18, 24); //眼黑 gr.setColor(Color.BLACK); gr.fillOval(x1+23, y1+36, 10, 14); gr.setColor(Color.BLACK); gr.fillOval(x1+78, y1+36, 10, 14); //嘴巴 Color mouse = new Color(248, 246, 229); gr.setColor(mouse); gr.fillOval(x1+37, y1+57, 40, 30); //鼻子 gr.setColor(Color.BLACK); gr.fillOval(x1+53, y1+50, 9, 9); //左耳 gr.setColor(Color.RED); gr.fillOval(x1+3, y1+3, 22, 22); //右耳 gr.setColor(Color.RED); gr.fillOval(x1+84, y1+3, 22, 22); Shape shape = new Shape(x1, y1, x2, y2, name); //保存shapeArray數(shù)組 shapeArray[index++] = shape; } } public void mouseEntered(MouseEvent e) { System.out.println("進(jìn)入"); } public void mouseExited(MouseEvent e) { System.out.println("退出"); } }
主類-----DrawFrame類
代碼如下:
package com.yf1014; import java.awt.FlowLayout; import java.awt.Graphics; import javax.swing.JButton; import javax.swing.JFrame; public class DrawFrame { //主程序(程序入口) public static void main(String[] args){ DrawFrame df = new DrawFrame(); df.showUI(); } //顯示畫圖工具的界面 public void showUI(){ MyFrame jf = new MyFrame(); jf.setTitle("畫圖工具"); jf.setSize(800, 700); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setLocationRelativeTo(null); //創(chuàng)建流式布局 jf.setLayout(new FlowLayout()); //添加各種類型的按鈕 JButton jbu = new JButton("直線"); jf.add(jbu); JButton jbu2 = new JButton("矩形"); jf.add(jbu2); JButton jbu3 = new JButton("小熊"); jf.add(jbu3); //設(shè)置可見 jf.setVisible(true); //畫筆:圖形畫在哪個組件上,畫筆就從該組件上獲取 //從窗體上獲取畫筆對象,一定要在窗體顯示可見之后 Graphics g = jf.getGraphics(); DrawMouse mouse = new DrawMouse(g); //給窗體添加鼠標(biāo)監(jiān)聽器方法 jf.addMouseListener(mouse); //給按鈕添加動作監(jiān)聽器 jbu.addActionListener(mouse); jbu2.addActionListener(mouse); jbu3.addActionListener(mouse); //把shapeArray數(shù)組傳遞到MyJFrame中 jf.setShapeArray(mouse.shapeArray); } }
輸出結(jié)果:
將窗體全屏顯示結(jié)果:
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
WebSocket實現(xiàn)系統(tǒng)后臺消息實時通知功能
在現(xiàn)代Web應(yīng)用中,提供實時通知對于改善用戶體驗至關(guān)重要,WebSocket技術(shù)允許建立雙向通信通道,從系統(tǒng)后臺將消息實時傳送給系統(tǒng)用戶,下面我們就來深入探討一下如何使用WebSocket來實現(xiàn)這一功能吧2023-10-10SpringBoot+Mybatis實現(xiàn)Mapper接口與Sql綁定幾種姿勢
通常我們在使用Mybatis進(jìn)行開發(fā)時,會選擇xml文件來寫對應(yīng)的sql,然后將Mapper接口與sql的xml文件建立綁定關(guān)系,然后在項目中調(diào)用mapper接口就可以執(zhí)行對應(yīng)的sql,感興趣的可以學(xué)習(xí)一下2021-09-09Springmvc應(yīng)用Mongodb分頁實現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Springmvc應(yīng)用Mongodb分頁實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11mybatis自動生成@Table、@Column、@Id注解的方法
這篇文章主要介紹了mybatis自動生成@Table、@Column、@Id注解的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Mybatis不啟動項目直接測試Mapper的實現(xiàn)方法
在項目開發(fā)中,測試單個Mybatis Mapper方法通常需要啟動整個SpringBoot項目,消耗大量時間,本文介紹通過Main方法和Mybatis配置類,快速測試Mapper功能,無需啟動整個項目,這方法使用AnnotationConfigApplicationContext容器2024-09-09SpringBoot整合Thymeleaf小項目及詳細(xì)流程
這篇文章主要介紹了SpringBoot整合Thymeleaf小項目,本項目使用SpringBoot開發(fā),jdbc5.1.48,主要涉及到Mybatis的使用,Thymeleaf的使用,用戶密碼加密,驗證碼的設(shè)計,圖片的文件上傳(本文件上傳到本地,沒有傳到數(shù)據(jù)庫)登錄過濾,需要的朋友可以參考下2022-03-03