You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义图标的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());

最终需求

  1. 按下时保留对应状态的自定义图标(未选中时按下显示未选中图标,选中时按下显示选中图标)
  2. 同时保留默认JCheckBox的按下效果(框体区域添加阴影)

即实现默认JCheckBox的按下效果,但替换为自定义图标。


内容的提问来源于stack exchange,提问作者Heneh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:13:10