M1 Mac环境下Java Swing JButton可点击但图片不显示问题求助
问题原因
- 重写的
paint方法逻辑错误:你在调用完screenDraw完成背景、组件绘制后,又直接调用g.drawImage(background, 0,0,null)绘制了一次背景,直接把已经渲染好的按钮等组件全部覆盖,导致视觉上看不到按钮,但组件本身的交互逻辑不受影响。 screenDraw方法错误调用repaint():repaint()会触发paint方法执行,相当于形成了无限循环的渲染调用,不仅浪费性能,还可能导致Swing渲染队列异常,组件无法正常绘制。setVisible(true)调用时机错误:你在还没有添加按钮、菜单栏等组件的时候就调用了窗口显示方法,后续添加的组件没有触发有效的渲染刷新,也可能导致组件不显示。- 额外M1兼容问题:M1芯片的Mac对部分旧版JDK的Swing渲染逻辑支持不佳,自定义双缓冲逻辑写法不规范的情况下更容易出现渲染异常。
解决方案
按顺序修改以下代码即可:
- 修正
paint方法逻辑,不要重复绘制背景覆盖组件,改为绘制双缓冲生成的完整画面:
public void paint(Graphics g) { screenImage = createImage(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT); screenGraphic = screenImage.getGraphics(); screenDraw(screenGraphic); // 替换原来的背景绘制,直接绘制包含背景+所有组件的缓冲图片 g.drawImage(screenImage, 0, 0, null); }
- 删除
screenDraw方法中的this.repaint()调用,避免无限渲染循环:
public void screenDraw(Graphics g) { g.drawImage(background, 0, 0, null); paintComponents(g); // 删掉本行代码:this.repaint(); }
- 调整
setVisible(true)的调用位置,从构造方法靠前的位置挪到构造方法的最后一行,保证所有组件添加完成后再显示窗口。 - 可选兼容优化:给startButton添加
startButton.setOpaque(false);配置,关闭按钮的默认不透明属性,避免M1设备上Swing默认渲染的背景遮挡图标;如果还是存在图片加载问题,可以将ImageIcon的加载方式替换为ImageIO.read(),加载稳定性更高。
内容的提问来源于stack exchange,提问作者Air김진호
相关产品推荐
相关产品推荐

