You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:20:59