JAVA学习日志之画图板重绘

画板类的代码:

package 画图板重绘;

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

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

//画板类
public class Huaban {
	Graphics g;
	public static void main(String[] args){
		Huaban hb = new Huaban();
		hb.show();
	}
	private void show() {
		JFrame jf = new JFrame();
		jf.setTitle("画图板重绘");
		jf.setSize(800, 800);
		//设置居中显示
		jf.setLocationRelativeTo(null);
		
		jf.setLayout(new FlowLayout());
		jf.setDefaultCloseOperation(3);
		//在画布上创建鼠标监听器
		Mouse m = new Mouse();
		jf.addMouseListener(m);
		
		//添加按钮
		String[] text = {"直线","矩形"};
		for(int i=0;i<text.length;i++)
		{
			JButton btn = new JButton(text[i]);
			jf.add(btn);
			btn.addActionListener(m);//给按钮添加动作监听器
		}
		jf.setVisible(true);
		//获取画笔
		Graphics g =  jf.getGraphics();
		//将画笔传到监听器去
		m.g = g;
	}
}

监听器代码:

package 画图板重绘;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Mouse implements MouseListener,ActionListener{
		Graphics g;
		String text = "";//按钮上的文字
		int x1,x2,y1,y2;
		
		//动作监听:当点击按钮的时候,获取按钮上的文字
		public void actionPerformed(ActionEvent e){
	    	text = e.getActionCommand();
	    }
		
	 	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();
	    	
	    	if("直线".equals(text))
	    	{
	    		g.drawLine(x1, y1, x2, y2);
	    	}
	    	if("矩形".equals(text))
	    	{
	    		g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
	    	}
	    }

	    public void mouseEntered(MouseEvent e){
	    }
	    public void mouseExited(MouseEvent e){
	    }
	    
}

如上代码实现的功能是在画图板界面上产生两个按钮:直线和矩形按钮。
当我们点击其中一个按钮的时候,用鼠标在界面上按住、释放,可以画出相应的直线和矩形。
效果如下:
在这里插入图片描述
但是当我们对窗口进行缩放的时候,我们原先画出的图会消失不见。这是因为当窗体在屏幕上显示的时候,首先是将窗体对象的数据从内存中取出来放到缓存中,再在屏幕上进行绘制。当窗体发生改变的时候,程序会重新从内存中获取更新后的数据进行绘制。我们画过的形状之所以会消失,就在于我们没有将画过的形状存放到内存中,所以当窗体发生重绘的时候就不会绘制了。
在系统中JFrame的父类中提供一个paint(Graphics g)的方法来负责将窗体数据在屏幕上绘制出来。
首先我们要将窗体类继承JFrame类,再重写JFrame类中的paint(Graphics g)方法:

package 画图板重绘;

import java.awt.Graphics;

import javax.swing.JFrame;

public class Rejframe extends JFrame{
	Shape[] s;
	
	public void paint(Graphics g){
		//一定要先调用父类的paint方法,用来绘制窗体
		super.paint(g);
		//写自己重绘的方法
		for(int i=0;i<s.length;i++)
		{	
			Shape shape = s[i];
		 if(shape!=null){
		
			if("直线".equals(shape.type))
			{
				g.drawLine(shape.x1, shape.y1,shape.x2, shape.y2);
			}
			if("矩形".equals(shape.type))
			{
				g.drawRect(Math.min(shape.x1,shape.x2), Math.min(shape.y1, shape.y2), Math.abs(shape.x1-shape.x2), Math.abs(shape.y1-shape.y2));
			}
		  }
		}
	}
}

我们需要在监听器中设置一个Shape(图形类)数组来记录画图需要的数据:

package 画图板重绘;
//图形类
public class Shape {
	int x1,x2,y1,y2;
	String type;
}

在监听器Mouse类中修改代码:

//创建图形类数组,每个单元存放一个图形
		Shape[] s = new Shape[10];
		//下标
		int index=0;

		public void mouseReleased(MouseEvent e){
	    	x2 = e.getX();
	    	y2 = e.getY();
	    	
	    	if("直线".equals(text))
	    	{
	    		g.drawLine(x1, y1, x2, y2);
	    		//创造shape类对象,将原图形的数据记录在缓存中
	    		Shape h = new Shape();
	    		h.x1 = x1;
	    		h.x2 = x2;
	    		h.y1 = y1;
	    		h.y2 = y2;
	    		h.type = "直线";
	    		s[index++] = h;
	    	}
	    	if("矩形".equals(text))
	    	{
	    		g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
	    		//创造shape类对象,将原图形的数据记录在缓存中
	    		Shape h = new Shape();
	    		h.x1 = x1;
	    		h.x2 = x2;
	    		h.y1 = y1;
	    		h.y2 = y2;
	    		h.type = "矩形";
	    		s[index++] = h;
	    	}
	    }

还有一个重要的点是,我们重新构造的Rejframe类具有属性Shape[] s,在画板类代码中,我们需要修改JFrame jf = new JFrame(); 为Rejframe jf = new Rejframe();,同时还需要将监听器中的shape类数组传到画板中的shape类数组中去,jf.s = m.s;这样我们的窗体就可以找到需要重绘的数据。

这样实现之后,我们对窗体进行缩放,改变窗体大小都不会使我们已画好的图形消失。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值