Java中图形界面重绘方法

**

Java中图形界面重绘方法

**
  在我们编写图形界面程序的过程中,我们就会发现,当我们将窗体拉伸,缩小(或者最大化最小化)的时候,之前在窗体上画的图形会消失了。

这是为什么呢?

1)原来,窗体包括其他的组件都是计算机绘制出来,我们一旦使得窗体发生改变,之前的一切都得重新绘制。但是,对于组件等有既定的重绘方法,对于我们所画的图形却没有重绘的方法。

2)也可以这样解释: 我们绘制图形的数据都存储在内存中,而整个窗体都是调用系统底层的绘图方法来绘制出来的。在创建窗体时我们已经定义了窗体的大小,如果我们再次改变窗体大小的时候,原来的窗体就不满足显示的需求。这时候就会将窗体上所有的组件再重新绘制一次。调用了paint方法,这个方法是定义在JFrame和JPanel中都有的。

  对于这样的情况,我们只需要去重写paint方法即可但是,这里有最为重要的一点,就是该类必须继承JFrame类或者JPanel类,不然不可以重写paint()!!!

  同时,我们需要注意一点还有: 数据的存储方式及获取方式,因为在程序运行中 addActionListener() 方法只会调用一次,事件处理方法会多次出发。所以如何将数据存储下来并接着在paint方法中使用是我们需要去考虑的。
  例如,我们可以先建立一个Shape类来记录图形信息,即坐标,类型等。
创建的Shape类的代码如下:

package com.yf1014;

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

/**
 * 图形类
 * @author yf
 *
 */

//Shape的主要功能:是记录图形信息,即坐标,类型等,然后根据所记录的图形信息来还原图像的。
public class Shape {
    
    
	//属性
	public int x1,y1,x2,y2;
	public String name;
	
	//方法分为构造方法和普通方法
	//构造方法  格式:public 类名(参数类型 参数名,,){}
	//普通方法  格式:public void 类名(参数类型 参数名,,){}
	//每个类都有一个默认的无参构造方法,当自己定义构造方法,默认的构造方法就会被替代
	//作用:1.创建对象    2.初始化属性
	//this:表示本类对象
	//此时该构造方法的作用是:
	//当创建对象时,将构造方法内传进来的参数赋给属性,这样我每创建一个新的对象时,该对象就拥有这些属性了。
	public Shape(int x1,int y1,int x2,int y2,String name){
    
    
		this.x1 = x1;//当参数名和属性名相同时,使用this来使得参数赋值给属性
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
		this.name = name;
	}
	//根据保存的数据还原图形对象
	public void drawShape(Graphics g){
    
    
		if("直线".equals(name)){
    
    
			g.drawLine(x1, y1, x2, y2);
		}
		else if("矩形".equals(name)) {
    
    
			g.drawRect(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
		}
		else if("小熊".equals(name)) {
    
    
			//头
			Color headColor = new Color(224, 178, 142);
			g.setColor(headColor);
			g.fillRect(x1, y1, 110, 110);
			g.fillArc(x1, y1, 20, 20, 1, 2);
			
			//眼睛
			g.setColor(Color.WHITE);
			g.fillOval(x1+20, y1+32, 18, 24);
			g.setColor(Color.WHITE);
			g.fillOval(x1+75, y1+32, 18, 24);
			
			//眼黑
			g.setColor(Color.BLACK);
			g.fillOval(x1+23, y1+36, 10, 14);
			g.setColor(Color.BLACK);
			g.fillOval(x1+78, y1+36, 10, 14);
			
			//嘴巴
			Color mouse = new Color(248, 246, 229);
			g.setColor(mouse);
			g.fillOval(x1+37, y1+57, 40, 30);
			
			//鼻子
			g.setColor(Color.BLACK);
			g.fillOval(x1+53, y1+50, 9, 9);
			
			//左耳
			g.setColor(Color.RED);
			g.fillOval(x1+3, y1+3, 22, 22);
			
			//右耳
			g.setColor(Color.RED);
			g.fillOval(x1+84, y1+3, 22, 22);  
			
			//Shape shape = new Shape(x1, y1, x2, y2, name);
		}		
	}
}

  然后创建一个MyFrame类,该类的主要作用就是重写paint方法。首先,在该类中,利用Shape类创建一个数组shapeArray来保存对象(用于保存图形信息,即坐标,类型等)。

MyFrame类的代码如下:

package com.yf1014;

import java.awt.Graphics;

import javax.swing.JFrame;

//MyFrame的主要功能是:是将保存在数组中的图形对象信息进行重绘,即重写paint方法的,因为需要在画布上操作,所以需要继承JFrame类。
public class MyFrame extends JFrame {
    
    
	
	// 定义Shape数组,保存对象(用于保存图形信息,即坐标,类型等)
	private Shape[] shapeArray;
	
	//利用普通方法,将传进来的数组类型shapeAraay赋给属性值,也可以采用的构造方法来进行该操作,换言之,这两种方法都可以来实现传参数给属性值
	public void setShapeArray(Shape[] shapeArray){
    
    
		this.shapeArray = shapeArray;
	}
	
	//重写paint方法
	public void paint(Graphics g) {
    
    
		super.paint(g);//先继承父类的paint方法,然后再利用下述方法重写paint方法

		//遍历setShapeArray数组,取出图形对象
		for(int i=0;i<shapeArray.length;i++){
    
    
			Shape shape = shapeArray[i];
			if(shape != null){
    
    
				shape.drawShape(g);    
			}
		}
	}
}

接着,我们就要创建一个DrawMouse监听器类,实现事件监听功能。

代码如下:

package com.yf1014;

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;

//事件处理类
public class DrawMouse implements MouseListener, ActionListener {
    
    
	// 定义Graphics变量gr,用来保存传递过来的文本框对象
	private Graphics gr;
	private int x1, y1, x2, y2;
	private String name;
	//定义Shape数组,保存对象(用于保存图形信息,即坐标,类型等)
	Shape[] shapeArray = new Shape[100];
	//操作数组的下标
	int index = 0;
	
	//构造方法,将传进来的参数g赋给属性gr
	public DrawMouse(Graphics g){
    
    
		gr = g;
	}

	// 定义set方法,初始化gr变量(即为普通方法,这个时候的功能是和上述的构造方法的功能是相同的,然而当我还需要传入另一个参数时,则需要利用普通方法来实现)
	//在本文中,构造方法DrawMouse和普通方法setGr可以任选其一即可。
	public void setGr(Graphics g) {
    
    
		gr = g;
	}
	
	//接下这些东西就是监听器MouseListener和ActionListener的抽象方法的重写。
	public void actionPerformed(ActionEvent e) {
    
    
		//获取按钮上的字符串
		name = e.getActionCommand();
		
		System.out.println("name = "+name);
	}
	public void mouseClicked(MouseEvent e) {
    
    
		System.out.println("点击");
		
		if(e.getClickCount() == 2){
    
    
			
		}
	}

	public void mousePressed(MouseEvent e) {
    
    
		System.out.println("按下");
		x1 = e.getX();
		y1 = e.getY();
	}

	public void mouseReleased(MouseEvent e) {
    
    
		System.out.println("松开");
		x2 = e.getX();
		y2 = e.getY();

		// 设置画笔颜色
		// gr.setColor(Color.BLUE);
		
		if("直线".equals(name)){
    
    
			// 画图
			gr.drawLine(x1, y1, x2, y2);
		
			//创建Shape对象,保存该图形的数据
			Shape shape = new Shape(x1, y1, x2, y2, name);
			//保存shapeArray数组
			shapeArray[index++] = shape;
		}
		else if("矩形".equals(name)){
    
    
			// 矩形
			gr.drawRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));
			//创建Shape对象,保存该图形的数据
			Shape shape = new Shape(x1, y1, x2, y2, name);
			//保存shapeArray数组
			shapeArray[index++] = shape;
		}
		else if("小熊".equals(name)) {
    
    
			//头
			Color headColor = new Color(224, 178, 142);
			gr.setColor(headColor);
			gr.fillRect(x1, y1, 110, 110);
			gr.fillArc(x1, y1, 20, 20, 1, 2);
			
			//眼睛
			gr.setColor(Color.WHITE);
			gr.fillOval(x1+20, y1+32, 18, 24);
			gr.setColor(Color.WHITE);
			gr.fillOval(x1+75, y1+32, 18, 24);
			
			//眼黑
			gr.setColor(Color.BLACK);
			gr.fillOval(x1+23, y1+36, 10, 14);
			gr.setColor(Color.BLACK);
			gr.fillOval(x1+78, y1+36, 10, 14);
			
			//嘴巴
			Color mouse = new Color(248, 246, 229);
			gr.setColor(mouse);
			gr.fillOval(x1+37, y1+57, 40, 30);
			
			//鼻子
			gr.setColor(Color.BLACK);
			gr.fillOval(x1+53, y1+50, 9, 9);
			
			//左耳
			gr.setColor(Color.RED);
			gr.fillOval(x1+3, y1+3, 22, 22);
			
			//右耳
			gr.setColor(Color.RED);
			gr.fillOval(x1+84, y1+3, 22, 22);
			
			Shape shape = new Shape(x1, y1, x2, y2, name);
			//保存shapeArray数组
			shapeArray[index++] = shape;
		}
	}

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

	public void mouseExited(MouseEvent e) {
    
    
		System.out.println("退出");
	}
	
}

主类-----DrawFrame类

代码如下:

package com.yf1014;

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

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

public class DrawFrame {
    
    
	//主程序(程序入口)
	public static void main(String[] args){
    
    
		DrawFrame df = new DrawFrame();
		df.showUI();
	}
	//显示画图工具的界面
	public void showUI(){
    
    
		MyFrame jf = new MyFrame();
		jf.setTitle("画图工具");
		jf.setSize(800, 700);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setLocationRelativeTo(null);
		//创建流式布局
		jf.setLayout(new FlowLayout());
		//添加各种类型的按钮
		JButton jbu = new JButton("直线");
		jf.add(jbu);
		JButton jbu2 = new JButton("矩形");
		jf.add(jbu2);
		JButton jbu3 = new JButton("小熊");
		jf.add(jbu3);
		//设置可见
		jf.setVisible(true);
		
		//画笔:图形画在哪个组件上,画笔就从该组件上获取
		//从窗体上获取画笔对象,一定要在窗体显示可见之后
		Graphics g = jf.getGraphics();
		
		DrawMouse mouse = new DrawMouse(g);
		//给窗体添加鼠标监听器方法
		jf.addMouseListener(mouse);
		
		//给按钮添加动作监听器
		jbu.addActionListener(mouse);
		jbu2.addActionListener(mouse);
		jbu3.addActionListener(mouse);
		
		//把shapeArray数组传递到MyJFrame中
		jf.setShapeArray(mouse.shapeArray);
	}
}

输出结果:

在这里插入图片描述
将窗体全屏显示结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39350172/article/details/109216844
今日推荐