你是不是也遇到过这样的问题:我们在窗体组件上绘制图形时,只要稍稍挪动一下窗体,刚刚绘制好的图形就会立马消失不见。
这是因为你在挪动窗体的时候,程序会进行刷新,重新绘制窗体,而不会绘制我们的图像。就像以下这样:
//窗体类
import java.awt.Graphics;
import javax.swing.Jframe;
public class Repaint extends Jframe{
public static void main(String[] args) {
Repaint r=new Repaint();
r.InitialUI();
}
//创建监听器对象
Line_Listener ll=new Line_Listener();
//初始化界面的方法
public void InitialUI() {
this.setSize(800,600);
this.setTitle("重绘举例");
this.setDefaultCloseOperation(3);
this.setVisible(true);
//给窗体加上鼠标监听器
this.addMouseListener(ll);
//在窗体可视化之后获取画笔
Graphics g=this.getGraphics();
//把画笔从监听器里传过来
ll.setGraphics(g);
}
}
//监听器类
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Line_Listener implements MouseListener{
int x1,y1,x2,y2;
Graphics g;
//设置画笔
public void setGraphics(Graphics g) {
this.g=g;
}
public void mousePressed(MouseEvent e) {
//鼠标按下时获取线的起点
x1=e.getX();
y1=e.getY();
}
public void mouseReleased(MouseEvent e) {
//鼠标释放时获取线的终点
x2=e.getX();
y2=e.getY();
//划线
g.drawLine(x1,y1,x2,y2);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
}
该程序也可以成功地画出一条直线,但是当扩大或缩小窗体时,直线会消失。那我们应该如何改进呢?
重绘的方法在画直线的时候,我们应该把数据保存起来,在刷新窗体时顺便把直线也一并画出来。主要包括以下几个步骤:
创建一个类保存图形数据
public class Shape {
int x1,y1,x2,y2;
Shape(int x1,int y1,int x2,int y2){
this.x1=x1;
this.y1=y1;
this.x2=x2;
this.y2=y2;
}
public void draw(Graphics g) {
g.drawLine(x1,y1,x2,y2);
}
}
在绘制后立即保存图像
//以下是改进后的方法
public void mouseReleased(MouseEvent e) {
//鼠标释放时获取线的终点
x2=e.getX();
y2=e.getY();
Shape shape1=new Shape(x1,y1,x2,y2);
//调用Shape类中的方法画直线
shape1.draw(g);
//把值传给数组
shape[index++]=shape1;
}
重写paint方法以取出保存了的对象
public void paint(Graphics g) {
super.paint(g);
for(int i=0;i
其完整代码如下:
//窗体类(主程序)
import java.awt.Graphics;
import javax.swing.Jframe;
public class Repaint extends Jframe{
public static void main(String[] args) {
Repaint r=new Repaint();
r.InitialUI();
}
//创建监听器对象
Line_Listener ll=new Line_Listener();
//创建数组
Shape shape[]=new Shape[100];
//初始化界面的方法
public void InitialUI() {
this.setSize(800,600);
this.setTitle("重绘举例");
this.setDefaultCloseOperation(3);
this.setVisible(true);
//给窗体加上鼠标监听器
this.addMouseListener(ll);
//在窗体可视化之后获取画笔
Graphics g=this.getGraphics();
//把画笔从监听器里传过来
ll.setGraphics(g);
//传递数组
shape=ll.shape;
}
public void paint(Graphics g) {
super.paint(g);
for(int i=0;i
这样重绘的功能就被我们实现了。
其实说白了,就是在绘制完之后用合适的数据结构把需要重绘的数据保存下来,然后在窗体刷新时一并把图像画出来。只是其中需要注意对象之间的传递,比如该例子中的画笔g和shape数组,否则很容易出现空指针的情况,这也是新手经常遇到的问题。
如有问题,欢迎留言评论,一起探讨噢~



