在上一个版本中即画图板(二)中,我们进行了代码重构,将一个类重构成了几个类,每个类负责一个模块,在这个版本中,我们主要解决一些bug和不足
需要解决的问题
窗体在改变大小的时候,在比原先窗体大的那部分画图形会发现画的图形没显示出来,在改变一下窗体才会显示出来
解决方案
解决图形在窗体改变大小时图形不显示:
解决方案:
这儿会用到一个方法,重绘,需要重写paint(Graphics g)方法,既然是重绘,所以就需要一个容器来保存以前画的那些图形,此版本中用的是LinkedList< T >,画笔每画一笔都保存下来
保存一个图形,相当于保存图形的一些属性,属性有,画图形用到的坐标,比如直线是起始点坐标和终点坐标,每个图形都有的画笔的颜色,宽度,为了方便保存这些属性,我们封装成一个类来保存,因为每个图形的属性都有共同点,我们封装一个抽象父类,要写其他具体图形类只需继承就可以了
//这儿只写直线的代码用来演示,在这段代码中可以看到我们并没有画直线,因为,我们已经把此条直线添加到了list中,下面一行执行repaint()方法将会对list中的所有图形都会重绘一遍,所以就没必要在这儿多画一次了
list.add(new ShapeLine(xStart, yStart, xEnd, yEnd, graphics.getColor(), graphics.getStroke()));//将直线添加到list中
repaint();//repaint()这个方法是用来调用paint()方法,促使paint()方法的执行,
//在窗口拖动时,讲list容器中的图形遍历,然后都画出来
@Override
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < list.size(); i++) {
list.get(i).repaint((Graphics2D) g);// 在窗口改变大小的时候重绘,将list中的图形重画一次
}
if (shape != null) {
shape.repaint((Graphics2D) g);// 显示当前鼠标拖动是画出来的图形
}
}
//父类
public abstract class Shape {
public int x, y, x1, y1, arcWidth, arcHeight;// 画图形需要的一些变量
public Color currentColor;// 画笔的颜色
public Stroke strock;// 设置画笔的宽度
public Shape(int x, int y, int x1, int y1, int arcWidth, int arcHeight, Color currentColor, Stroke strock) {
// 圆角矩形的属性赋值
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.arcWidth = arcWidth;// 角弧度的水平直径。
this.arcHeight = arcHeight;// 角弧度的垂直直径。
this.currentColor = currentColor;
this.strock = strock;
}
public Shape(int x, int y, int x1, int y1, Color currentColor, Stroke strock) {
// 直线,矩形,
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.currentColor = currentColor;
this.strock = strock;
}
public abstract void repaint(Graphics2D g);// 抽象方法,用画笔画图形
}
//这儿也只演示直线类,继承父类Shape
public class ShapeLine extends Shape {
public ShapeLine(int x, int y, int x1, int y1, Color currentColor, Stroke strock) {
super(x, y, x1, y1, currentColor, strock);
}
// 重绘制直线
@Override
public void repaint(Graphics2D g) {
g.setColor(currentColor);
g.setStroke(strock);
g.drawLine(x, y, x1, y1);
}
}
为了使画图形一目了然,添加了一点效果,拖动的时候显示图形:
//还是以直线为例,当然,这效果肯定是在拖动鼠标的时候显示的,所以在鼠标拖动的事件里写的
//这一行代码作用:直线起始点不变,就是鼠标按下的哪一点,终点随着鼠标拖动的变化而变化,,然后记录此时起始点和鼠标之间的一条直线,并不是保存在list里面,因为鼠标还在拖动的过程中还没有释放,只是临时的显示出来
//shape是一个Shape类型的全局变量,
shape = new ShapeLine(xStart, yStart, e.getX(), e.getY(),graphics.getColor(),graphics.getStroke());
repaint();//将鼠标拖动时的图形绘制出来,调用paint()方法
//在paint()方法中的if语句中就是将鼠标拖动时的图形画出来
@Override
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < list.size(); i++) {
list.get(i).repaint((Graphics2D) g);// 在窗口改变大小的时候重绘,将list中的图形重画一次
}
if (shape != null) {
shape.repaint((Graphics2D) g);// 显示当前鼠标拖动是画出来的图形
}
}