做过简单画板后,就会发现,当窗体缩放或最小化之后,所绘制的图形都会消失,这是因为所绘制的图形并没有存放到内存中,所以当窗体改变后就没有数据来让它重绘。那为了解决这一问题,最直截了当的方法就是用一个队列来储存所绘过的数据,在重绘时将这些数据再一次“画”出来。
[注]:这里为了更明白的显示重绘的代码,画图板只绘制直线。
首先要创建一个储存图形对象的队列,我们以前做的队列是String型的,那为了提高它的利用率,就可以把它改成不定型(E)的,即自定义泛型队列。代码如下:
public class MyArray<E>{
Object[] a = new Object[0];
//装数据的方法
public void add(E s){
Object[] tem = new Object[a.length+1];
for(int i=0;i<a.length;i++)
tem[i]=a[i];
tem[a.length]=s;
a=tem;
}
// 取出对应下标的元素
public E get(int index){
if(index<0||index>=a.length){
throw new RuntimeException("传入的下标超出边界:"+a.length);
}
return (E)a[index];
}
// 返回容器中的元素个数
public int size(){
return a.length;
}
}
那么,我们就需要在Drawline这个类中定义一个用来保存形状对象的队列,这时E就变成我们所需要的shape型了:
public static MyArray<Shape> shapes = new MyArray<Shape>();
既然我们使用了shape这一个类型,就要创建相应的shape类,这个类中要有画线的方法:
public class Shape {
int x1,y1,x2,y2;
public void draw(Graphics g){
g.drawLine(x1, y1, x2, y2);
}
}
这样,准备工作就做好了,我们可以往画板的代码中加入重绘的成分。在监听器中将形状对象存入队列:
public class DrawListener implements MouseListener {
//定义属性,储存坐标
static int x1,y1,x2,y2;
//定义绘制图形图像对象的属性
private Graphics g;
//构造绘制图形图像的方法
public DrawListener(Graphics g){
this.g=g;
}
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
//获取鼠标按下时的坐标值
x1 = e.getX();
y1 = e.getY();
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
//获取鼠标释放时的坐标值
x2 = e.getX();
y2 = e.getY();
//创建直线对象
Shape sh = new Shape();
sh.x1=x1;
sh.y1=y1;
sh.x2=x2;
sh.y2=y2;
//绘制形状
sh.draw(g);
//将形状对象存入队列
Drawline.shapes.add(sh);
}
}
[注]: 继承MouseListener所需要实现的其它方法这里就不一一列出了。
最后,只要在Drawline这个类中加入如下代码即可:
//获取画布对象
Graphics g = this.getGraphics();
//重写绘制窗体的方法
public void paint(Graphics g){
//调用父类的方法来绘制窗体
super.paint(g);
for(int i=0;i<shapes.size();i++){
Shape sh = shapes.get(i);
//绘制形状
sh.draw(g);
}
}
这样,我们就完成了简单画板的一种重绘。