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
相关产品推荐
相关产品推荐

