使用画图板画图时,我们往往会遇到这样的问题:当拖动窗体改变窗体大小或将窗体最小化后,我们绘画的图形往往会消失。这是因为,使用画笔绘画的图像是保存在缓存中,当我们改变窗体大小或最小化时,窗体上的内容就会被清空。
因此,为了保存窗体上的内容,我们需要对绘制的图形进行重绘。
重绘的主要思想是将我们绘制的图形数据储存起来,在窗体初始化时利用paint方法调用这些数据进行图形重绘。
因此,实现重绘的主要步骤在于如何将存储图形的数据储存起来。
重绘的方法有许多,比如在这篇文章中即将提到的图形对象重绘,即把绘制的图形看做一个对象,对图形的坐标、颜色、绘图动作命令等列入一个数组,在重绘时遍历这些数组绘制图像;
接下来,我们来介绍一下图形对象重绘的方法:
1. 构建Shape类
在简易的画图板构建完毕后,我们已经写好了两个类,一个是界面设置的DrawUI类,另一个窗体监听DrawListener类,此时,为了方便重绘时,我们新建一个Shape 类。
public class Shape {
public int x1,x2,y1,y2;
String name;
Color color;
BufferedImage buffimg;
public Shape(int x1,int x2,int y1,int y2,String name,Color color) {
this.x1=x1;
this.x2=x2;
this.y1=y1;
this.y2=y2;
this.name=name;
this.color=color;
}
}
Shape类中主要属性值绘图动作的坐标x1,y1,x2,y2,以及图形颜色color和图形名称(即图形的绘图动作)name,还有绘图时所使用的缓冲画布buffimg。
将绘图的主要方法从监听类中移至Shape类中,如下
public void Drawshape(Graphics g) {
buffimg=new BufferedImage(800,600,BufferedImage.TYPE_INT_ARGB);
Graphics bg = buffimg.getGraphics();
bg.setColor(color);
switch(name){
case"直线":
bg.drawLine(x1, y1, x2, y2);
break;
case"矩形":
bg.drawRect(Math.min(x1,x2), Math.min(y1, y2), Math.abs(x2-x1), Math.abs(y2-y1));
break;
case"圆形":
bg.drawOval(Math.min(x1,x2), Math.min(y1, y2),Math.abs(x2-x1), Math.abs(y2-y1));
break;
}
g.drawImage(buffimg,0,0,null);
}
2. 使用Shape型数组保存图形参数
在监听类DrawListener中添加Shape型数组,用来保存图形参数,
Shape[] shapearr = new Shape[1000];
3. 存储图形对象参数
修改画图板监听类的mouseReleased方法,将监听窗体获得的坐标、颜色、和绘图动作命令赋值给shape对象,调用Shape类中Drawshape方法进行绘图,并将坐标、颜色、绘图动作命令等属性值添加进数组shapearr中,方便重绘时调用。
public void mouseReleased(MouseEvent e) {
x2=e.getX();
y2=e.getY();
System.out.println("释放"+"x="+e.getX()+"y="+e.getY());
Shape shape=new Shape(x1,x2,y1,y2,typestr,color);
shape.Drawshape(g);
shapearr[shapeindex]=shape;
shapeindex++;
}
并在DrawListener中添加getshapearr方法传入Shape值
public Shape[] getshapearr() {
return shapearr;
}
4. 重写paint方法
在paint方法中,对shape内数组进行遍历,重绘图像。
public class DrawPanel extends JPanel{
Shape[] shapearr;
int count=0;
public void setShapearr(Shape[] shapearr) {
this.shapearr = shapearr;
}
@Override
public void paint(Graphics g) {
super.paint(g);
count++;
System.out.println("panel paint");
//绘制图形
for(int i=0;i<shapearr.length;i++){
if(shapearr[i] != null){
//shape.Drawshape(g);
System.out.println("shape"+shapearr[i].buffimg);
g.drawImage(shapearr[i].buffimg, 0, 0, null);
}
}
}
}
最后,在初始化界面的方法中利用监听获取shape数组,并将shape数组数据传给界面以调用重绘方法。
shapearr=dl.getshapearr();
c_jp.shapearr = shapearr;