Java Swing调用JButton.getIcon().toString()触发NullPointerException求助
问题根因
- 空指针错误触发原因:你初始化按钮时没有设置默认Icon,仅在用户点击时才给按钮赋值Icon,因此只要存在未被点击的按钮,调用
getIcon()就会返回null,直接调用toString()方法就会触发空指针异常。 - 现有代码还有两处隐藏错误:
- 最初的if判断逻辑漏了
buttons[9]的校验,重复判断了两次buttons[8],即使修复空指针问题也无法正确判断胜负。 - 你拿
ImageIcon.toString()的返回值和PlayerSetting.getShape()做内容比较的逻辑本身就是错误的:ImageIcon的toString()返回的是类名、哈希值等类信息,不是你构造ImageIcon时传入的形状/路径字符串,就算所有按钮都填充了Icon,你也永远匹配失败。同时你代码中用==比较字符串内容的写法也是错误的,Java字符串内容比较必须使用equals()方法。
修复方案
推荐你新增一个单独的数组存储格子填充状态,不要依赖Icon做业务判断,逻辑更清晰也不会出现空指针问题:
步骤1:新增状态存储数组
在按钮数组同级位置新增一个数组存储每个格子的填充内容:
// 25个格子对应25个状态位,初始化默认值为null String[] gridStatus = new String[25];
步骤2:点击时同步更新状态
在用户/AI点击按钮设置Icon的同时,同步更新状态数组:
// 玩家点击逻辑部分 Clicked.setIcon(new ImageIcon(PlayerSetting.getShape())); // 新增:获取当前点击按钮的索引,更新状态数组 int clickIdx = Arrays.asList(buttons).indexOf(Clicked); gridStatus[clickIdx] = PlayerSetting.getShape();
AI点击逻辑部分也同理添加对应状态更新代码。
步骤3:修改胜负判断逻辑
直接遍历状态数组做判断,完全规避空指针风险:
boolean isWin = Arrays.stream(gridStatus).allMatch(shape -> PlayerSetting.getShape().equals(shape)); if (isWin) { System.out.println("Win"); } else { System.out.println("Not Yet"); }
如果你不想新增状态数组,非要通过Icon判断,也可以先做空指针校验再做判断(不推荐,Icon的toString比较逻辑仍需你自行调整为正确判断规则):
boolean isWin = Arrays.stream(buttons).allMatch(button -> { Icon icon = button.getIcon(); // 空Icon直接返回false,规避空指针 if (icon == null) return false; // 这里的比较规则需要你自行修改为正确逻辑,当前toString比较是错误的 return icon.toString().equals(PlayerSetting.getShape()); });
内容的提问来源于stack exchange,提问作者ItzYahPizza
相关产品推荐
相关产品推荐

