Java中的圖形界面重繪方式
Java圖形界面重繪方式
在我們編寫圖形界面程序的過程中,我們就會(huì)發(fā)現(xiàn),當(dāng)我們將窗體拉伸,縮?。ɑ蛘咦畲蠡钚』┑臅r(shí)候,之前在窗體上畫的圖形會(huì)消失了。
這是為什么呢?
1)原來,窗體包括其他的組件都是計(jì)算機(jī)繪制出來,我們一旦使得窗體發(fā)生改變,之前的一切都得重新繪制。但是,對(duì)于組件等有既定的重繪方法,對(duì)于我們所畫的圖形卻沒有重繪的方法。
2)也可以這樣解釋: 我們繪制圖形的數(shù)據(jù)都存儲(chǔ)在內(nèi)存中,而整個(gè)窗體都是調(diào)用系統(tǒng)底層的繪圖方法來繪制出來的。在創(chuàng)建窗體時(shí)我們已經(jīng)定義了窗體的大小,如果我們?cè)俅胃淖兇绑w大小的時(shí)候,原來的窗體就不滿足顯示的需求。這時(shí)候就會(huì)將窗體上所有的組件再重新繪制一次。調(diào)用了paint方法,這個(gè)方法是定義在JFrame和JPanel中都有的。
對(duì)于這樣的情況,我們只需要去重寫paint方法即可。 但是,這里有最為重要的一點(diǎn),就是該類必須繼承JFrame類或者JPanel類,不然不可以重寫paint()?。?!
同時(shí),我們需要注意一點(diǎn)還有:
- 數(shù)據(jù)的存儲(chǔ)方式及獲取方式,因?yàn)樵诔绦蜻\(yùn)行中 addActionListener() 方法只會(huì)調(diào)用一次,事件處理方法會(huì)多次出發(fā)。
- 所以如何將數(shù)據(jù)存儲(chǔ)下來并接著在paint方法中使用是我們需要去考慮的。
例如,我們可以先建立一個(gè)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ù)名,,){}
//每個(gè)類都有一個(gè)默認(rèn)的無參構(gòu)造方法,當(dāng)自己定義構(gòu)造方法,默認(rèn)的構(gòu)造方法就會(huì)被替代
//作用:1.創(chuàng)建對(duì)象 2.初始化屬性
//this:表示本類對(duì)象
//此時(shí)該構(gòu)造方法的作用是:
//當(dāng)創(chuàng)建對(duì)象時(shí),將構(gòu)造方法內(nèi)傳進(jìn)來的參數(shù)賦給屬性,這樣我每創(chuàng)建一個(gè)新的對(duì)象時(shí),該對(duì)象就擁有這些屬性了。
public Shape(int x1,int y1,int x2,int y2,String name){
this.x1 = x1;//當(dāng)參數(shù)名和屬性名相同時(shí),使用this來使得參數(shù)賦值給屬性
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.name = name;
}
//根據(jù)保存的數(shù)據(jù)還原圖形對(duì)象
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)建一個(gè)MyFrame類,該類的主要作用就是重寫paint方法。
首先,在該類中,利用Shape類創(chuàng)建一個(gè)數(shù)組shapeArray來保存對(duì)象(用于保存圖形信息,即坐標(biāo),類型等)。
MyFrame類
代碼如下:
package com.yf1014;
import java.awt.Graphics;
import javax.swing.JFrame;
//MyFrame的主要功能是:是將保存在數(shù)組中的圖形對(duì)象信息進(jìn)行重繪,即重寫paint方法的,因?yàn)樾枰诋嫴忌喜僮?,所以需要繼承JFrame類。
public class MyFrame extends JFrame {
// 定義Shape數(shù)組,保存對(duì)象(用于保存圖形信息,即坐標(biāo),類型等)
private Shape[] shapeArray;
//利用普通方法,將傳進(jìn)來的數(shù)組類型shapeAraay賦給屬性值,也可以采用的構(gòu)造方法來進(jìn)行該操作,換言之,這兩種方法都可以來實(shí)現(xiàn)傳參數(shù)給屬性值
public void setShapeArray(Shape[] shapeArray){
this.shapeArray = shapeArray;
}
//重寫paint方法
public void paint(Graphics g) {
super.paint(g);//先繼承父類的paint方法,然后再利用下述方法重寫paint方法
//遍歷setShapeArray數(shù)組,取出圖形對(duì)象
for(int i=0;i<shapeArray.length;i++){
Shape shape = shapeArray[i];
if(shape != null){
shape.drawShape(g);
}
}
}
}
接著,我們就要?jiǎng)?chuàng)建一個(gè)DrawMouse監(jiān)聽器類,實(shí)現(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ù)組,保存對(duì)象(用于保存圖形信息,即坐標(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è)時(shí)候的功能是和上述的構(gòu)造方法的功能是相同的,然而當(dāng)我還需要傳入另一個(gè)參數(shù)時(shí),則需要利用普通方法來實(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("點(diǎn)擊");
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對(duì)象,保存該圖形的數(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對(duì)象,保存該圖形的數(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);
//畫筆:圖形畫在哪個(gè)組件上,畫筆就從該組件上獲取
//從窗體上獲取畫筆對(duì)象,一定要在窗體顯示可見之后
Graphics g = jf.getGraphics();
DrawMouse mouse = new DrawMouse(g);
//給窗體添加鼠標(biāo)監(jiān)聽器方法
jf.addMouseListener(mouse);
//給按鈕添加動(dòng)作監(jiān)聽器
jbu.addActionListener(mouse);
jbu2.addActionListener(mouse);
jbu3.addActionListener(mouse);
//把shapeArray數(shù)組傳遞到MyJFrame中
jf.setShapeArray(mouse.shapeArray);
}
}
輸出結(jié)果:

將窗體全屏顯示結(jié)果:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
分布式調(diào)度XXL-Job整合Springboot2.X實(shí)戰(zhàn)操作過程(推薦)
這篇文章主要介紹了分布式調(diào)度XXL-Job整合Springboot2.X實(shí)戰(zhàn)操作,包括定時(shí)任務(wù)的使用場(chǎng)景和常見的定時(shí)任務(wù),通過本文學(xué)習(xí)幫助大家該選擇哪個(gè)分布式任務(wù)調(diào)度平臺(tái),對(duì)此文感興趣的朋友一起看看吧2022-04-04
RabbitMQ 3.9.7 鏡像模式集群與Springboot 2.5.5 整合
今天我們來聊聊 RabbitMQ 3.9.7 鏡像模式集群與Springboot 2.5.5 整合,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-10-10
詳解spring-boot下如何滿足多生產(chǎn)環(huán)境中個(gè)性化定制功能
這篇文章主要介紹了詳解spring-boot下如何滿足多生產(chǎn)環(huán)境中個(gè)性化定制功能,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03
你不知道的 IDEA Debug調(diào)試小技巧(小結(jié))
這篇文章主要介紹了你不知道的 IDEA Debug調(diào)試小技巧(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
Struts1教程之ActionMapping_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Struts1教程之ActionMapping,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
Java14發(fā)布了,再也不怕NullPointerException了
這篇文章主要介紹了Java14發(fā)布了,再也不怕NullPointerException了,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2020-03-03

