`
Kslsi
  • 浏览: 22573 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

队列及画图板的重绘实现

    博客分类:
  • java
阅读更多

       在画图板的实现那一节课中,我们发现我们所画出来的图形会在一段时间内慢慢消失,而且当把画图板最小化之后,画图板就会恢复成没画图形的样子(白板),我们知道,这是由于界面的重绘所致,为了解决这个问题,我们就应该给我们绘制的图形写一个重绘方法,但是,我们每次绘画图形的地点是不一样的,这就让我们想到用大型数组将我们画的图形存起来,但又有一个问题,再大的数组它也是有界的,当我们越界之后那不就出错了?这可怎么办呢?于是乎,我们学习了队列:

 

        队列是设计程序中常用的一种数据结构。它类似日常生活中的排队现象,采用一种被称为“先进先出”(LIFO)的存储结构。数据元素只能从队尾进入,从队首取出。在队列中,数据元素可以任意增减,但数据元素的次序不会改变。每当有数据元素从队列中被取出,后面的数据元素依次向前移动一位。所以,任何时候从队列中读到的都是队首的数据。
  根据这些特点,我们可以对队列定义以下五种操作(当然,肯定不止这五种,大家可以再去实现其它的操作):                                

                             从队列删除指定的一个对象

                                  取得队列中指定位置的一个对象 

                                  删除指定index索引处的学生对象  

                                  向队列的index位置插入一个对象

                                  向队列中加一个对象(加在末尾)

public class CustomListReal<E> implements CustomList<E>{

	private Object []srcA = new Object [0];
	
	/**
	 * 向队列中加一个对象(加在末尾)
         */
	public void add(E e) {

		//1.新建一个数组,长度为原数组长度+1
		Object [] stuA = new Object [srcA.length+1];
		//2.将要加入的对象放入新数组的最后一个位置
		stuA[srcA.length] = e;
		//3.将原数组里的东西放到新数组中
		for(int t = 0 ;t<srcA.length;t++){
			stuA[t] = srcA[t];
		}
		//4.将新数组赋给旧的
		srcA = stuA;
	}

	/**
	 * 向队列的index位置插入一个指定对象
	 */
	public void add(E e, int index) {
		
		//1.新建一个数组,长度为原数组长度+1
		Object [] stuA = new Object[srcA.length+1];
		//2.在index以后的对象从后向前依次附给后面
		for(int i = srcA.length; i>index; i--){
			stuA[i] = srcA[i-1];
		}
		//3.将要加入的对象放在index位置,index之前的对象保持不变
		stuA[index] = e;
		for(int i = index-1; i>=0;i--){
			stuA[i] = srcA[i]; 
		}
		//4.将新数组附给旧数组
		srcA = stuA;
	}
	
	/**
	 * 删除index索引处的学生对象
	 */
	public boolean delete(int index) {
		
		//1.新建一个数组,长度为原数组长度-1
		Object [] stuA = new Object[srcA.length-1];
		
		//2.将index后面的数依次赋给前面
		for(int i = index; i<srcA.length-1;i++)
			stuA[i] = srcA[i+1];
		
		//3.将要删除的对象放在index位置,index之前的对象保持不变
		for(int i = index-1; i>=0;i--){
			stuA[i] = srcA[i]; 
		}
		System.out.println(srcA[index].toString().charAt(index)+"已被删除");
		//4.将新数组附给旧数组
		srcA = stuA;
		return true;
	}
        /**
        * 删除指定的一个对象
         */
	public boolean delete(E e) {
		boolean state = true;
		//1.新建一个数组,长度为原数组长度-1
		Object [] stuA = new Object[srcA.length-1];
		
		//2.遍历数组,找到要删除的对象
		for(int i = 0;i<srcA.length;i++){
			//如果找到
			if(srcA[i] == e){
				//将在i位置后面的数依次赋给前一个
				for(int j = i;j<srcA.length-1;j++){
					stuA[j] = srcA[j+1];
				}
				//i前面的不变
				for(int j = i-1;j >= 0;j--){
					stuA[j] = srcA[j];
				}
                        //3.将新数组赋给旧的
			srcA = stuA;
			state = true;
			}else{//如果没找到
				state = false;
			}
		}
		if(state == true){
			return true;
		}
		return false;	
	}
	

       /**
       * 取得队列中指定位置的一个对象
        *@return st 一个学生对象
        */
	public E get(int index) {
		E st = (E)srcA[index];
		return st;
	}
}

 

       有了这些(其实只要有添加方法),我们就可以实现画图板图形的重绘了,把之前做的画图板调出来,将我们写的重绘方法添加进去就好了,举一个重绘直线的例子:

1.创建自定义队列的接口

/**
 * 自定义队列的接口
 * @author Administrator
 */
public interface CustomList <E>{
	
	//向队列中加一个对象
	public void add(E e);
}

 

2.创建自定义队列实现类

/**
 * 创建一个自定义队列的实现类,该类实现CustomList
 * @author ZhuMei
 */
public class CustomListReal<E> implements CustomList<E>{

	private Object []srcA = new Object [0];
	
	/**
	 * 向队列中加一个对象
	 */
	public void add(E e) {

		//1.新建一个数组,长度为原数组长度+1
		Object [] stuA = new Object [srcA.length+1];
		//2.将要加入的对象放入新数组的最后一个位置
		stuA[srcA.length] = e;
		//3.将原数组里的东西放到新数组中
		for(int t = 0 ;t<srcA.length;t++){
			stuA[t] = srcA[t];
		}
		//4.将新数组赋给旧的
		srcA = stuA;
	}
}

 

3.绘制直线的类:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;

/**
 * 绘制直线的类,该类继承自Shape抽象类
 * @author ZhuMei
 *
 */
public class ShapeLine extends Shape {

	/**
	 * 构造方法
	 */
	public ShapeLine(int x1, int y1, int x2, int y2, Color color, int stroke) {
		super(x1, y1, x2, y2, color, stroke);
	}

	/**
	 * 绘制图形的方法
	 */
	public void draw(Graphics2D g) {
		g.setStroke(new BasicStroke(getStroke()));//设置线条粗细
		g.setColor(getColor());//设置线条颜色
		g.drawLine(getX1(), getY1(), getX2(), getY2());
	}

}

 4.在监听器中绘制直线:

/**
 * 在事件源上发生鼠标释放的时候执行
*/
public void mouseReleased(MouseEvent e){
	x2 = e.getX();
	y2 = e.getY();
	
        if(db.getShapeType().equals("Line")){
		g.drawLine(x1, y1, x2, y2);
		// 实例化一个绘制直线的方法
		shape = new ShapeLine(x1, y1, x2, y2, Color.BLACK, 1);
		// 调用绘制图形的方法
		shape.draw(g);
		cl.add(shape);
	}

 5.在画板中实例化自定义队列的列表

private CustomList<Shape> cl = new CustomListReal<Shape>();

6 .在画板中重写重绘方法

public void paint(Graphics g){
	super.paint(g);
				
	//遍历队列
	for(int i=0;i<cl.size();i++){
	         Shape shape = cl.get(i);
	         shape.draw((Graphics2D)g);
	}
}
			

      这样做了,我们画的直线就不会无缘无故的消失了,我们也可以用同样的方法实现其它图形的重绘了。不过还得解释一下E,这个是java中的泛型,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。当我们在这儿CustomList中使用之后,除了画板,其它的类型的队列是可以用的。

       就写到这儿吧,编程,是应该在模仿中创新的,大家一起加油吧!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics