自定义图标的JCheckBox按下状态绘制异常:始终显示选中图标
自定义JCheckBox按下状态图标异常问题
我需要一个带自定义图标的JCheckBox,但设置自定义图标后,复选框在按下(pressed)状态下绘制异常——无论当前是否选中,按下时始终显示选中图标。
相关代码
主测试类(snippet 1)
package demos.button; import di.Icons; import javax.swing.*; import java.awt.*; public class CheckBoxDemo { public static void main(String[] args) { JFrame frame = new JFrame("Check Box demo"); JPanel mainPanel = createMainPanel(); frame.setContentPane(mainPanel); frame.setLocationRelativeTo(null); frame.pack(); frame.setVisible(true); } private static JPanel createMainPanel() { FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.CENTER); JPanel mainPanel = new JPanel(layout); mainPanel.add(createCheckBox()); return mainPanel; } private static JCheckBox createCheckBox() { JCheckBox checkBox = new JCheckBox(); checkBox.setIcon(Icons.unchecked()); checkBox.setSelectedIcon(Icons.checked()); return checkBox; } }
图标工具类(snippet 2)
package di; import util.IconUtil; import javax.swing.*; public class Icons { private Icons() { } public static Icon checked() { return IconUtil.findIcon("/checked.gif").orElse(null); } public static Icon unchecked() { return IconUtil.findIcon("/unchecked.gif").orElse(null); } }
图标加载工具类(snippet 3)
package util; import javax.swing.*; import java.net.URL; import java.util.Optional; public class IconUtil { private IconUtil() { } public static Optional<Icon> findIcon(String path) { URL iconUrl = IconUtil.class.getResource(path); return Optional.ofNullable(iconUrl).map(ImageIcon::new); } }
异常现象说明
- 使用的自定义图标:选中状态图标(checked.gif)、未选中状态图标(unchecked.gif)
- 未设置自定义图标时无此问题:
// snippet 4 private static JCheckBox createCheckBox() { JCheckBox checkBox = new JCheckBox(); return checkBox; }
这与setIcon()的文档描述矛盾,文档明确说明:
Sets the button's default icon. This icon is also used as the "pressed" and "disabled" icon if there is no explicitly set pressed icon.
我已将未选中图标设为默认图标,按文档说明,复选框在按下状态时应显示该图标,但实际显示的却是选中图标。将borderPainted属性设为true后,现象更明显——按下时复选框始终呈现选中状态:
// snippet 5 private static JCheckBox createCheckBox() { JCheckBox checkBox = new JCheckBox(); checkBox.setIcon(Icons.unchecked()); checkBox.setSelectedIcon(Icons.checked()); checkBox.setBorderPainted(true); return checkBox; }
就像我错误地执行了:
// snippet 6 checkBox.setIcon(Icons.checked());
而非正确的:
// snippet 7 checkBox.setIcon(Icons.unchecked());
最终需求
- 按下时保留对应状态的自定义图标(未选中时按下显示未选中图标,选中时按下显示选中图标)
- 同时保留默认JCheckBox的按下效果(框体区域添加阴影)
即实现默认JCheckBox的按下效果,但替换为自定义图标。
内容的提问来源于stack exchange,提问作者Heneh
相关产品推荐
相关产品推荐

