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

JDK17环境下AWT Canvas添加至JPanel绘制内容不显示问题问询

问题根因

这个问题和你引入的SWT依赖无关,属于AWT/Swing原生绘制机制的问题,具体原因如下:

  • 你使用Canvas.getGraphics()获取的是临时绘制上下文,这种方式绘制的内容只会保留到下一次组件重绘前。只要窗口触发重绘(比如首次显示、调整大小、被遮挡后重新展示、系统主动触发重绘),Swing/AWT的默认重绘逻辑会直接清空组件表面的所有临时绘制内容,你首次调用绘制的内容在窗口显示时就被清掉了。
  • 你的绘制时机错误:你在Canvas还没有被添加到窗口容器、没有和系统原生窗口资源(peer)绑定的时候就调用了绘制方法,这时候拿到的Graphics对象本身是无效的,绘制内容根本不会落到实际显示的组件表面。
  • 如果你没有使用IDE GUI生成器的隐式调用逻辑,你自定义的createUIComponents()初始化方法没有被主动调用,会导致BufferedImage、Canvas、JPanel这些核心对象没有完成初始化,绘制逻辑自然无法生效。
  • 你观测到的鼠标移动时闪烁的现象,是因为鼠标移动事件会触发组件重绘,你在鼠标事件回调里的绘制刚好插在两次重绘的间隙,马上就会被下一次重绘清空,所以只会短暂显示出现闪烁效果。

修复方案

正确的做法是重写Canvas的paint(Graphics g)方法,把你的绘制逻辑放到这个方法里,Swing/AWT每次重绘组件时都会自动调用这个方法,绘制内容会持续显示:

// 替换你原来创建Canvas的逻辑
cnv = new Canvas() {
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        // 直接把预生成的BufferedImage画出来
        g.drawImage(bf, 0, 0, this);
    }
};
cnv.setSize(100, 100);

如果需要主动触发刷新,调用cnv.repaint()即可,不要手动用getGraphics()做持久化绘制。

内容的提问来源于stack exchange,提问作者fjsantosaorin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:15:01