java之画图板浅析(二)---实现重绘及拓展_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java之画图板浅析(二)---实现重绘及拓展

java之画图板浅析(二)---实现重绘及拓展

 2013/10/19 12:47:44  逆天子军少  程序员俱乐部  我要评论(0)
  • 摘要:在我的上一篇博客(http://1316478764.iteye.com/admin/blogs/1948471),我简单实现了一个画图板,但是仍有很大的bug,当窗体大小发生改变时,我们会发现之前画的图形会遭到破坏,甚至最小化后再打开,图形完全消失。导致这个bug的原因也很简单,因为内存中没有保存这些图形,接下来我们就具体探讨一下这个问题。首先我们要知道当窗体大小发生改变时,系统会自动调用JFrame的paint方法,因为我们画的图形是存在缓存中,当窗体大小改变后,这些缓存会自动清空
  • 标签:实现 Java 画图 重绘
在我的上一篇博客(http://1316478764.iteye.com/admin/blogs/1948471),我简单实现了一个画图板,但是仍有很大的bug,当窗体大小发生改变时,我们会发现之前画的图形会遭到破坏,甚至最小化后再打开,图形完全消失。导致这个bug的原因也很简单,因为内存中没有保存这些图形,接下来我们就具体探讨一下这个问题。
首先我们要知道当窗体大小发生改变时,系统会自动调用JFrame的paint方法,因为我们画的图形是存在缓存中,当窗体大小改变后,这些缓存会自动清空,paint方法不会重绘这些图形,只会重绘窗体上的组件。知道所以然后就好办了,我们要做的就是将这些图形保存到内存中,当窗体进行重绘时,再将这些图形从内存中取出,画出来,即重写paint方法。
至于怎么保存图形,学过队列的童鞋肯定无压力,我们可以创建一个保存图形类对象的队列,当我们在画图板上每画一个图形,就保存一个,然后重写paint方法时,我们只需要遍历这个队列,将保存的图形在画出来就ok了。看点代码吧:
class="java" name="code">public class MyList<E> {
	private Object src[] = new Object[0];

	public void add(E e) {
		Object dest[] = new Object[src.length + 1];
		dest[src.length] = e;
		System.arraycopy(src, 0, dest, 0, src.length);
		src = dest;
	}

	public E get(int index) {
		Object e = src[index];
		return (E) e;
	}

队列中需要哪些方法,是根据我们想实现的功能来决定的,我们想实现重绘的话,上面两个方法应该够用了。
至于图形类,我们创建一个Shape类,里面包含了图形的每个属性,还有画图形的方法,代码如下:
public class Shape {
    int x1,y1,x2,y2;//画图形需要的起点和终点坐标
    Color color;//线的颜色
    Stroke st;//画笔的粗细
    Byte type;//金字塔:0    立方体:1    鸡蛋:2
    Boolean flag=true;//用作标记shape对象是否显示(用于撤销和重做)true:显示  false:不显示
    
    public void drawShape(Graphics g){此处省略若干行代码}

保存图形类的队列我们已经实现,接下来我们只要给Shape类的各个属性赋值,画出图形并保存图形
		  //绘制图形
		shape.drawShape(g);
		
		//将图形保存到队列中
		shapeList.add(shape);

到这儿就基本完成工作了,最后我们只需重写画布的paint方法
public void paint(Graphics g){	
					super.paint(g);	
		    //note:一定要取对画布!!!获取jp_addto的画布,所以在jp_addtojp里重写paint方法更好,还能避免上方jpanel的闪烁
				//遍历队列,重新绘制出保存到图形
				for(int i=0;i<shapeList.size();i++){	
					Shape shape=shapeList.get(i);
					shape.drawShape(g);
				}
			}

ok,我们在运行看看,会发现最小化后再打开,还是能看到之前的图形,嘎嘎,是不是感觉自己又进步了一点。但是难道重绘只能这样应用么,我们还能不能用重绘来完成其他的功能呢??
当然可以,还记得你画错图形但却不能删除的苦恼么么,我们通过重绘就可以实现撤销和重做操作,还可以实现清空画布。撤销不就是把刚刚保存的Shape对象不画出来,然后再重绘,而重做不就是将之前不让画出来的图形再画出来么。这两个功能我们通过对每个Shape对象设置一个标志决定是否画出来来实现,即上面Shape类代码中定义的flag属性。至于清空画布就更简单,我们将队列中的所有Shape类对象全删了不就完事。当然,这需要我们在队列中添加delete方法。
发表评论
用户名: 匿名