**
Java中图形界面重绘方法
**
在我们编写图形界面程序的过程中,我们就会发现,当我们将窗体拉伸,缩小(或者最大化最小化)的时候,之前在窗体上画的图形会消失了。
这是为什么呢?
1)原来,窗体包括其他的组件都是计算机绘制出来,我们一旦使得窗体发生改变,之前的一切都得重新绘制。但是,对于组件等有既定的重绘方法,对于我们所画的图形却没有重绘的方法。
2)也可以这样解释: 我们绘制图形的数据都存储在内存中,而整个窗体都是调用系统底层的绘图方法来绘制出来的。在创建窗体时我们已经定义了窗体的大小,如果我们再次改变窗体大小的时候,原来的窗体就不满足显示的需求。这时候就会将窗体上所有的组件再重新绘制一次。调用了paint方法,这个方法是定义在JFrame和JPanel中都有的。
对于这样的情况,我们只需要去重写paint方法即可。 但是,这里有最为重要的一点,就是该类必须继承JFrame类或者JPanel类,不然不可以重写paint()!!!
同时,我们需要注意一点还有: 数据的存储方式及获取方式,因为在程序运行中 addActionListener() 方法只会调用一次,事件处理方法会多次出发。所以如何将数据存储下来并接着在paint方法中使用是我们需要去考虑的。
例如,我们可以先建立一个Shape类来记录图形信息,即坐标,类型等。
创建的Shape类的代码如下:
package com.yf1014;
import java.awt.Color;
import java.awt.Graphics;
/**
* 图形类
* @author yf
*
*/
//Shape的主要功能:是记录图形信息,即坐标,类型等,然后根据所记录的图形信息来还原图像的。
public class Shape {
//属性
public int x1,y1,x2,y2;
public String name;
//方法分为构造方法和普通方法
//构造方法 格式:public 类名(参数类型 参数名,,){}
//普通方法 格式:public void 类名(参数类型 参数名,,){}
//每个类都有一个默认的无参构造方法,当自己定义构造方法,默认的构造方法就会被替代
//作用:1.创建对象 2.初始化属性
//this:表示本类对象
//此时该构造方法的作用是:
//当创建对象时,将构造方法内传进来的参数赋给属性,这样我每创建一个新的对象时,该对象就拥有这些属性了。
public Shape(int x1,int y1,int x2,int y2,String name){
this.x1 = x1;//当参数名和属性名相同时,使用this来使得参数赋值给属性
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.name = name;
}
//根据保存的数据还原图形对象
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);
}
}
}
然后创建一个MyFrame类,该类的主要作用就是重写paint方法。首先,在该类中,利用Shape类创建一个数组shapeArray来保存对象(用于保存图形信息,即坐标,类型等)。
MyFrame类的代码如下:
package com.yf1014;
import java.awt.Graphics;
import javax.swing.JFrame;
//MyFrame的主要功能是:是将保存在数组中的图形对象信息进行重绘,即重写paint方法的,因为需要在画布上操作,所以需要继承JFrame类。
public class MyFrame extends JFrame {
// 定义Shape数组,保存对象(用于保存图形信息,即坐标,类型等)
private Shape[] shapeArray;
//利用普通方法,将传进来的数组类型shapeAraay赋给属性值,也可以采用的构造方法来进行该操作,换言之,这两种方法都可以来实现传参数给属性值
public void setShapeArray(Shape[] shapeArray){
this.shapeArray = shapeArray;
}
//重写paint方法
public void paint(Graphics g) {
super.paint(g);//先继承父类的paint方法,然后再利用下述方法重写paint方法
//遍历setShapeArray数组,取出图形对象
for(int i=0;i<shapeArray.length;i++){
Shape shape = shapeArray[i];
if(shape != null){
shape.drawShape(g);
}
}
}
}
接着,我们就要创建一个DrawMouse监听器类,实现事件监听功能。
代码如下:
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,用来保存传递过来的文本框对象
private Graphics gr;
private int x1, y1, x2, y2;
private String name;
//定义Shape数组,保存对象(用于保存图形信息,即坐标,类型等)
Shape[] shapeArray = new Shape[100];
//操作数组的下标
int index = 0;
//构造方法,将传进来的参数g赋给属性gr
public DrawMouse(Graphics g){
gr = g;
}
// 定义set方法,初始化gr变量(即为普通方法,这个时候的功能是和上述的构造方法的功能是相同的,然而当我还需要传入另一个参数时,则需要利用普通方法来实现)
//在本文中,构造方法DrawMouse和普通方法setGr可以任选其一即可。
public void setGr(Graphics g) {
gr = g;
}
//接下这些东西就是监听器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();
// 设置画笔颜色
// gr.setColor(Color.BLUE);
if("直线".equals(name)){
// 画图
gr.drawLine(x1, y1, x2, y2);
//创建Shape对象,保存该图形的数据
Shape shape = new Shape(x1, y1, x2, y2, name);
//保存shapeArray数组
shapeArray[index++] = shape;
}
else if("矩形".equals(name)){
// 矩形
gr.drawRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));
//创建Shape对象,保存该图形的数据
Shape shape = new Shape(x1, y1, x2, y2, name);
//保存shapeArray数组
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数组
shapeArray[index++] = shape;
}
}
public void mouseEntered(MouseEvent e) {
System.out.println("进入");
}
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);
//创建流式布局
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);
//设置可见
jf.setVisible(true);
//画笔:图形画在哪个组件上,画笔就从该组件上获取
//从窗体上获取画笔对象,一定要在窗体显示可见之后
Graphics g = jf.getGraphics();
DrawMouse mouse = new DrawMouse(g);
//给窗体添加鼠标监听器方法
jf.addMouseListener(mouse);
//给按钮添加动作监听器
jbu.addActionListener(mouse);
jbu2.addActionListener(mouse);
jbu3.addActionListener(mouse);
//把shapeArray数组传递到MyJFrame中
jf.setShapeArray(mouse.shapeArray);
}
}
输出结果:
将窗体全屏显示结果: