画板重绘

    起初的画板设计,由于系统缓存的局限,缩放画板窗体后便不能呈现画板上的对象,鉴于此,需要我们改进画板。

    引进自定义队列,我们就可以“记住”画板上已画的图案,并重绘出来显示在原窗体上。

    先创建一个DrawUI类,完成一般画板工作,代码如下:

   

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

/**
 * 画图板重绘
 * 
 * @author Administrator
 */

@SuppressWarnings("serial")
public class DrawUI extends JFrame{
	
	public static void main(String args[]) {
		new DrawUI();
	}
  /**
    *初始化界面 
    */
	public DrawUI() {
		this.setTitle("画图板界面");
		this.setSize(600, 500);
		this.setDefaultCloseOperation(3);

		//设置布局
		FlowLayout layout = new FlowLayout();
		this.setLayout(layout);
		
		JButton line = new JButton("直线");
		//设置按钮的动作命令
		line.setActionCommand("line");
		
		JButton rect = new JButton("矩形");
		rect.setActionCommand("rect");
		
		this.add(line);
		this.add(rect);
		
		this.setVisible(true);
		
		//创建动作监听器,加在按钮上
		ButtonListener blis = new ButtonListener();
		line.addActionListener(blis);
		rect.addActionListener(blis);
		
		//从窗体上获取画布对象
		//获取窗体在屏幕上所占据的区域,这块区域是允许改变颜色的
		java.awt.Graphics g = this.getGraphics();
		
		DrawListener dlis = new DrawListener(g,blis,this);
		//给窗体添加鼠标监听器
		this.addMouseListener(dlis);
		
	}
				
	
}

    这样的画板我们是不能“记住”所绘的图案的 。需要插入自定义队列来暂时保存信息。

    所以我们需要重写JFrame类中的用来绘制窗体的方法,加在DrawUI类后,代码如下:

/**
		 * 重写JFrame类中用来绘制窗体的方法
		 */
		public void paint(Graphics g){
			//调用父类的方法来正确的绘制窗体
			super.paint(g);
			
			//如果数组存在,就重绘数据
			if(null!= DrawListener.image){
		//重绘数组
		for(int i=0;i<DrawListener.image.length;i++){
		    	for(int j=0;j<DrawListener.image[i].length;j++){
			//获取颜色
			int c =DrawListener.image[i][j];
			//创建颜色对象
			Color color = new Color(c);
			g.setColor(color);
			g.drawLine(j, i, j, i);
			}
					
		}
	    }
			
	}

 

    但是,这样的代码还是有错的,DrawListener和ButtonListener监听器所在的类需要我们补充完整,代码如下:

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;


/**
 * 画板的监听器类,实现鼠标监听器接口
 * 
 * @author Administrator
 *
 */
public class DrawListener implements java.awt.event.MouseListener {
	
		private int x1,y1,x2,y2;
		private Graphics gr;
		private ButtonListener blis;
		
		private String type = "rect";// 要绘制的形状 rect 矩形 oval 椭圆
		private DrawUI du;
		
		java.awt.Robot robot;
		public static int image[][];
		
		//创建监听器对象的时候要求传入一个画布对象
		public DrawListener(Graphics gr,ButtonListener blis,DrawUI dlis){
		
				this.gr = gr;
				this.blis = blis;
				this.du = dlis;
				
				try{
					robot = new java.awt.Robot();
				}catch(AWTException e){
					e.printStackTrace();
				}
		}
				
		public DrawListener(Graphics g, ButtonListener blis2, DrawListener dlis) {
		}

		public void mousePressed(MouseEvent e){
			// 鼠标按下时候光标的位置
			x1 = e.getX();
			y1 = e.getY();
		}
		
		
		public void mouseReleased(MouseEvent e) {
			// 绘制之前先确定要绘制的形状类型
			type = blis.command;

			gr.setColor(new Color(0, 0, 0));

			// 鼠标释放时候光标的位置
			x2 = e.getX();
			y2 = e.getY();
			
			if (type.equals("line")) {
				// 画直线
				gr.drawLine(x1, y1, x2, y2);

			} else if (type.equals("rect")) {

				for (int i = 0; i < 200; i++) {

					gr.setColor(new Color(i, i, i));
					gr.drawRect(Math.min(x1, x2) + i, Math.min(y1, y2) - i, Math
							.abs(x2 - x1), Math.abs(y2 - y1));
				}
				
			}else if (type.equals("oval")){
				gr.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1),
						Math.abs(y2 - y1));
            }

			// 获取窗体左上角的位置和窗体大小
			Point p = du.getLocationOnScreen();
			Dimension dim = du.getSize();
			// 创建矩形对象
			java.awt.Rectangle rect = new java.awt.Rectangle(p, dim);
			// 截取屏幕
			BufferedImage img = robot.createScreenCapture(rect);

			image = new int[img.getHeight()][img.getWidth()];
			//将图像按照像素分割成一个一个的点,将点的颜色存入数组
			for(int i=0;i<image.length;i++){
				for(int j=0;j<image[i].length;j++){
					//将颜色存入数组
					image[i][j] = img.getRGB(j, i);
				}
			}
			
		}

		public void mouseEntered(MouseEvent e) {
			// System.out.println("mouseEntered");
		}

		public void mouseExited(MouseEvent e) {
			// System.out.println("mouseExited");
		}
		
		public void mouseClicked(MouseEvent e) {
			// System.out.println("mouseClicked");
		}
}

 

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 按钮的监听器
 * 
 * @author Administrator
 * 
 */
public class ButtonListener implements ActionListener {

	public String command;

	public void actionPerformed(ActionEvent e) {
		// 获取被点击的组件上的动作命令
		command = e.getActionCommand();
		System.out.println(command);
	}
}

 

    可以看到,在DrawListener类中完成了画板重绘。

    代码运行后,显然还是不能满足我们的需求,因为缩放后队列是按一定顺序依次展开呈现的,而不是一次全部展现,这需要我们更向前一步,在创建队列“记住图案”后能快速重绘。

    我的想法是不从自定义队列方面下手,因为队列鉴于其本质是一定先后顺序的先进先出的线性表,而这不可避免的会产生延迟,达不到我们的要求,而引进某种其他工具,能多维的,没有先后之分的拷贝窗体上的信息,这样既满足我们的要求,效率又得到了大大提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值