AWT Canvas绘制图形仅显示半秒即消失,代码无异常求排查
问题排查与解决方案
核心问题原因
你直接通过canvas.getGraphics()获取绘图上下文绘制的内容是临时的,不属于AWT/Swing的标准重绘流程。当窗口初始化完成后,系统会自动触发Canvas的paint方法进行重绘操作,此时之前绘制的临时内容会被清空,导致图形只显示一瞬间就消失。
修复方案
AWT/Swing的正确绘图方式是重写组件的paint方法,让绘图逻辑跟随系统的重绘机制执行,这样图形就能持久保留。以下是修改后的完整代码:
import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class GameWindow { private JFrame frame; private CustomCanvas canvas; private JPanel content; private int fieldSize; public GameWindow(int fieldSize) { this.fieldSize = fieldSize; frame = new JFrame(); frame.setTitle("Nonogramm"); frame.setSize(1000, 1000); frame.setResizable(false); // 用常量替代魔法数,提升代码可读性 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); content = new JPanel(); content.setLayout(null); frame.setContentPane(content); canvas = new CustomCanvas(); canvas.setBounds(200, 200, 600, 600); canvas.setBackground(Color.WHITE); content.add(canvas); // 将窗口显示操作放在最后,确保所有组件初始化完成后再触发重绘 frame.setVisible(true); } // 自定义Canvas子类,重写paint方法实现持久绘图 private class CustomCanvas extends Canvas { @Override public void paint(Graphics g) { // 先调用父类paint方法,确保组件背景等基础绘制完成 super.paint(g); drawField(g); } private void drawField(Graphics g) { g.setColor(Color.GREEN); int cellSize = 600 / fieldSize; for(int i = 0; i < 600; i += cellSize) { g.fillRect(i, 0, cellSize - 1, cellSize - 1); } } } public static void main(String[] args) { // 示例:传入fieldSize=10 new GameWindow(10); } }
关键修改点说明
- 自定义
CustomCanvas继承自Canvas,重写paint方法:该方法会在组件需要重绘时自动被系统调用(比如窗口初始化、窗口大小变化、最小化恢复等),确保图形始终存在。 - 调整
frame.setVisible(true)的位置:放在所有组件初始化完成后,避免组件未准备好就触发重绘。 - 替换魔法数:用
JFrame.EXIT_ON_CLOSE代替数字3,代码更易读。 - 移除
g.dispose():paint方法传入的Graphics对象由系统管理,无需手动释放。
内容的提问来源于stack exchange,提问作者TeeeTime
相关产品推荐
相关产品推荐

