Java中的图形界面重绘方式
作者:feng之锋
这篇文章主要介绍了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); } }
输出结果:
将窗体全屏显示结果:
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。