画图板的重绘

现在我们已经可以开发一个画图板程序了。但细心一点会发现,当我们对画图板的窗体最小化或者改变大小的时候,我们先前用鼠标在窗体上画的东西就会全部没有了。
这是因为 窗体在屏幕上显示的时候,首先会将窗体对象的数据从内存中取出来放到缓存中,然后在屏幕上绘制,窗体改变的时候又会重新执行一遍这个步骤。我们画的形状并没有保存下来,窗体重绘是,自然就消失了。
要解决这个问题,只需要将我们用鼠标画的形状保存下来,并让窗体重绘时将我们画的形状也跟着重绘一遍即可。

1.创建Shape类保存画图所需数据

在我们画图过程中,需要保存的数据有点的坐标,需要画的是什么形状(是直线,矩形还是椭圆),另外还有颜色。Shape类代码如下:

2.继承JFrame类

我们要重写paint方法,首先要让界面类继承paint方法(paint方法在JFrame类里面)。代码如下:

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

public class Shape {
     private int x1,x2,y1,y2;
     private Color color;
     private String name;
     //重载构造方法
     public Shape(){
    	 
     }
     public Shape(int x1,int y1,int x2,int y2,Color color,String name){	
 		this.x1 = x1;
 		this.y1 = y1;
 		this.x2 = x2;
 		this.y2 = y2;
 		this.color=color;
 		this.name = name;
 		
 	}
     
     public void SetShape(int x1,int y1,int x2,int y2,Color color,String name){
    	 this.x1 = x1;
    	 this.y1 = y1;
    	 this.x2 = x2;
    	 this.y2 = y2;
    	 this.color = color;
    	 this.name = name;
     }
     //重绘时所需的方法
     public void DrawShape(Graphics g){
    	 switch(name){
    	    case "直线":
    	    	 g.drawLine(x1, y1, x2, y2);g.setColor(color);
    	    	break;
    	    case "矩形":
    	    	g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
    	    	g.setColor(color);
    	    	break;
    	    case "椭圆":
    	    	g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
    	    	g.setColor(color);
    	    	break;
    	 }
     }
}

2.创建Shape数组保存数据

我们用鼠标在画图板上画图形时,每画一次,监听器里面的数据就会被赋值一次,所以我们可以在监听器里面创建数组保存画图所需数据,代码如下:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;

public class FrameListener implements MouseListener, ActionListener {
    private  Graphics g;
    private Color color;//定义颜色属性
    private String name;//接受按钮上的文字
    private int x1,y1,x2,y2;
    public Shape[] array = new Shape[100];	//创建Shape数组保存所需数据
    private int index=0;//操作数组的下标
    
    public void setGr(Graphics g){
    	this.g = g;    // 传输画笔对象 
    }
    public Shape[] getShape(){
    	return array;//方便重写paint方法获得数组
    }
    
   // 操作添加ActionListener的对象时调用此方法
	public void actionPerformed(ActionEvent e) {
    	//操作按钮时获取按钮信息,并对是文字还是颜色进行分类
    	if(e.getActionCommand().equals("")){
    		         JButton jbuc=(JButton)e.getSource();
 //可以获得JButton的所有信息,e.getSource();可以获取所有组件信息string name2=e.getText。
    				   color = jbuc.getBackground();
    			}
    			else{
    				name = e.getActionCommand();//如果按钮上有文字,获取文字,用name变量保存
    			}	
	}
    
    public void mouseClicked(MouseEvent e) {
		
	}

	
	public void mousePressed(MouseEvent e) {
	  x1=e.getX();
	  y1=e.getY();//获取按压时的点坐标	
	}


	public void mouseReleased(MouseEvent e) {
	  x2=e.getX();
	  y2=e.getY();//获取释放时候点的坐标
	  g.setColor(color);//可以通过对按钮执行按压操作改变画笔的颜色
	  // 创建图形对象
      Shape shape = new Shape();
	  
		if("直线".equals(name))    
			g.drawLine(x1, y1, x2, y2);//画直线
	       shape.SetShape(x1, y1, x2, y2, color, name);
	       // 调用构造方法将数据保存到数组中
		    array[index++] = shape;	
		
		if("矩形".equals(name))   
			g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
	       shape.SetShape(x1, y1, x2, y2, color, name);
	       // 调用构造方法将数据保存到数组中
		    array[index++] = shape;	
		
		if("椭圆".equals(name))  
			g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
	       shape.SetShape(x1, y1, x2, y2, color, name);
	       // 调用构造方法将数据保存到数组中
		    array[index++] = shape;	
	}

	public void mouseEntered(MouseEvent e) {
		
		
	}


	public void mouseExited(MouseEvent e) {
	
		
	}
}

3.重写paint方法

要重写paint方法,首先我们要让界面类继承JFrame,(paint方法在JFrame类中)。代码如下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;

public class DrawFrame extends JFrame {
	private static final long serialVersionUID = 1L;
	
	public Shape [] shapeArray = new Shape[100];
	public static void main(String []args){
		DrawFrame df = new DrawFrame();
		df.Frame();
	}
	
   public void Frame(){
	   this.setTitle("画板");
	   this.setSize(700,800);
	   this.setLocationRelativeTo(null);
	   this.setDefaultCloseOperation(3);	  
	   this.getContentPane().setBackground(Color.white);
	   FlowLayout layout = new FlowLayout(FlowLayout.CENTER, 40, 10);
	   this.setLayout(layout);
	   
	   FrameListener fl = new FrameListener();//创建监听器对象
	   String btname [] = {"直线","矩形","椭圆"};
	   for(int i=0;i<btname.length;++i){
		   JButton jbu = new JButton(btname[i]);
		   jbu.setPreferredSize(new Dimension(60,30));
		   jbu.addActionListener(fl);
		   this.add(jbu);
	   }
	   String colorname[] = {"红色","黑色","蓝色"};
	   Color [] color = {Color.red,Color.black,Color.blue};
	   for(int j=0;j<colorname.length;++j){
		   JButton jbu = new JButton();
		   jbu.setBackground(color[j]);
		   jbu.setPreferredSize(new Dimension(60,30));
		   jbu.addActionListener(fl);
		   this.add(jbu);	   
	   }
	   this.setVisible(true);
	   
	   
	 //画笔:图形画在那个组件上,画笔就从改组件上获取
	 //从窗体上获取画笔对象,一定要在窗体显示可见之后
	   Graphics g = this.getGraphics();
	   this.addMouseListener(fl);//给窗体添加监听器方法
	   fl.setGr(g);//将画笔对象传到监听器
	    shapeArray=fl.getShape();
   }
   // 重写paint方法
   public void paint(Graphics g){
	   super.paint(g);   //调用父类中被子类隐藏的方法,此步很重要,如果没有,界面也不会重绘
	   for(int i=0;i<100;i++){
		   Shape shape = shapeArray[i];
			if(shape != null){
				shape.DrawShape(g);
			}else{
				break;
			}
		}
   }
}
   

通过这三步,就能完成画图板的重绘。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值