Java AWT无Swing鼠标绘线:窗口缩放后线条消失求助
解决AWT Canvas绘制线条最小化后消失的问题
嘿,这个问题我太熟悉了!你遇到的情况是AWT组件重绘机制导致的——当窗口最小化再恢复时,系统会重新绘制Canvas,而你直接用getGraphics()画的内容是临时的,不会被持久保存,所以一刷新就没了。下面给你说清楚怎么解决:
问题根源
AWT的Canvas默认在需要重绘(比如窗口状态变化、组件大小改变)时,会调用paint()方法,这个方法默认会清空画布。你之前用c.getGraphics()获取的绘图上下文是临时的,画上去的内容不会被系统记录,所以重绘后就消失了。
解决方案:持久化绘制数据并重写paint方法
我们需要把所有绘制的线条保存起来,每次重绘时重新把这些线条画出来,步骤如下:
- 用一个集合存储所有线条的坐标信息(比如每条线的起点和终点)
- 重写
Canvas的paint()方法,遍历集合重新绘制所有线条 - 在鼠标拖拽时,把新的线条数据加入集合,然后触发重绘
修改后的完整代码
import java.awt.*; import java.awt.event.*; import java.util.ArrayList; class Drawing extends WindowAdapter implements MouseMotionListener, MouseListener, ComponentListener { Frame f; Canvas c; int X=400,Y=400; int px=-1,py=-1; // 用ArrayList存储所有线条,每个元素是一个包含4个int的数组:[起点x,起点y,终点x,终点y] ArrayList<int[]> lines = new ArrayList<>(); public Drawing() { f=new Frame("Drawing - Canvas"); f.addWindowListener(this); f.addComponentListener(this); f.setSize(X,Y); // 重写Canvas的paint方法 c=new Canvas(){ @Override public void paint(Graphics g) { super.paint(g); // 遍历所有线条,重新绘制 for(int[] line : lines){ g.drawLine(line[0], line[1], line[2], line[3]); } } }; f.add(c); c.addMouseMotionListener(this); c.addMouseListener(this); f.setVisible(true); } // 以下是你原来的空实现,保留即可 public void componentResized(ComponentEvent e) {} public void componentHidden(ComponentEvent e) {} public void componentMoved(ComponentEvent e) {} public void componentShown(ComponentEvent e) {} public void mouseMoved(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseDragged(MouseEvent e) { int x=e.getX(); int y=e.getY(); if(px!=-1) { // 把线条数据加入集合 lines.add(new int[]{px, py, x, y}); // 触发重绘,让paint方法重新画所有线条 c.repaint(); } px=x; py=y; } public void mouseReleased(MouseEvent e) { this.px=-1; this.py=-1; } public void windowClosing(WindowEvent e) { f.dispose(); } public static void main(String[] args) { Drawing c=new Drawing(); } }
关键改动说明
- 新增了
ArrayList<int[]> lines来存储每一条绘制的线条,每条线用四个整数记录起点和终点坐标 - 创建Canvas时重写了
paint()方法,每次重绘都会遍历集合把所有线条重新画一遍 mouseDragged()里不再直接用getGraphics()画线,而是把线条数据存入集合,然后调用repaint()触发系统重绘- 移除了
mouseReleased()里不必要的X和Y赋值
这样修改后,不管窗口怎么最小化、最大化或者调整大小,绘制的线条都会被持久保存并重新绘制出来啦!
内容的提问来源于stack exchange,提问作者Akash
相关产品推荐
相关产品推荐

