Red Hat 7.6环境Java Swing自定义光标抛IllegalArgumentException求助
问题重现
运行自定义光标代码时,日志已确认图片加载为32×32,但立刻抛出如下异常:
Warning: cursor image loaded 32 32
[AwtExceptionHandler:45] Error in AWT#012
<|>java.lang.IllegalArgumentException: Width (0) and height (0) must be non-zero
<|>at java.awt.image.ReplicateScaleFilter.(ReplicateScaleFilter.java:85)
<|>at java.awt.Image.getScaledInstance(Image.java:156)
<|>at sun.awt.CustomCursor.(CustomCursor.java:52)
<|>at sun.awt.X11CustomCursor.(X11CustomCursor.java:26)
<|>at sun.awt.X11.XCustomCursor.(XCustomCursor.java:27)
<|>at sun.awt.X11.XToolkit.createCustomCursor(XToolkit.java:878)
...
环境为Red Hat 7.6 + JDK 1.6,同配置其他环境无此问题,排除代码问题,怀疑环境变量影响。测试代码如下:
import java.awt.Cursor; import java.awt.Point; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JFrame; public class Main { static JFrame frame; private static final Logger logger = Logger.getLogger("asmacs"); private static final String BIG_CROSS = "big_cross.gif"; public static void main(String[] args) { create(); } public static JFrame create() { frame = new JFrame("teste"); frame.setSize(500, 500); frame.setVisible(true); frame.setCursor(getCursorCross()); return frame; } private static Cursor getCursorCross() { Toolkit tk = Toolkit.getDefaultToolkit(); int hotSpot = 32; BufferedImage image = null; try{ image = ImageIO.read(Main.class.getClassLoader().getResource(BIG_CROSS)); int width = image.getWidth(); int height = image.getHeight(); logger.warning("cursor image loaded " + width + " " + height); } catch (Exception e) { logger.warning(" error loading image "); } return tk.createCustomCursor(image, new Point(hotSpot, hotSpot), "cross"); } }
排查方向与解决方案
1. 强制设置Xcursor尺寸
JDK 1.6的X11Toolkit在创建自定义光标时,会读取系统Xcursor的尺寸设置,如果系统设置的光标尺寸与图片不匹配,可能触发错误缩放导致宽高为0。运行程序前在终端执行:
export XCURSOR_SIZE=32
强制光标尺寸与图片一致,避免自动缩放。
2. 切换默认光标主题
部分自定义光标主题可能干扰AWT的光标处理逻辑,切换到系统默认主题:
export XCURSOR_THEME=default
3. 调整图片转换逻辑
将BufferedImage转换为Toolkit原生支持的Image对象,避免AWT内部缩放错误。修改getCursorCross方法的返回逻辑:
// 替换原return语句 Image toolkitImage = tk.createImage(image.getSource()); return tk.createCustomCursor(toolkitImage, new Point(hotSpot, hotSpot), "cross");
4. 检查Java运行时参数
查看是否有影响图形渲染的_JAVA_OPTIONS参数,比如启用OpenGL加速可能导致光标处理异常,尝试移除相关参数,或添加:
export _JAVA_OPTIONS="-Dsun.awt.disableMixing=true"
禁用AWT的混合渲染逻辑,避免冲突。
验证步骤
- 在终端执行上述环境变量设置命令
- 重新编译并运行测试代码
- 观察是否再抛出宽高为0的异常,同时确认自定义光标正常显示
内容的提问来源于stack exchange,提问作者Nom

