java - 如何复制 JCheckBox 的禁用外观?

标签 java swing user-interface checkbox

采用以下示例代码。 Swing 中存在一些错误,如果组件包含 HTML,则不会将禁用的组件呈现为禁用状态。除了报告这个问题(我希望同事已经解决了这个问题)之外,还有什么好的方法可以解决这个问题吗?

无论我采取什么解决方案,我都希望它是一个全局修复,而不是需要侵入应用程序中的每个复选框。

我尝试为复选框制作一个自定义 UI,在绘画之前和之后调用 setForeground,但事实证明,通过调用 setForeground,它会触发一个事件,该事件最终导致它调用 repaint(),从而调用渲染器,...

import java.awt.GridLayout;
import java.util.Arrays;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class TestCheckBoxes extends JFrame
{
    public TestCheckBoxes()
    {
        JCheckBox checkBox1 = new JCheckBox("Enabled, plain text");
        JCheckBox checkBox2 = new JCheckBox("<html><p>Enabled, HTML");
        JCheckBox checkBox3 = new JCheckBox("Disabled, plain text");
        checkBox3.setEnabled(false);
        JCheckBox checkBox4 = new JCheckBox("<html><p>Disabled, HTML");
        checkBox4.setEnabled(false);

        setLayout(new GridLayout(4, 1));

        for (JCheckBox checkBox : Arrays.asList(checkBox1, checkBox2, checkBox3, checkBox4))
        {
            checkBox.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
            add(checkBox);
        }

        ((JComponent) getContentPane()).setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
        pack();
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                TestCheckBoxes frame = new TestCheckBoxes();
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

最佳答案

您可以将复选框和标签分离到它们自己的组件中,并简单地创建一个不带标签的复选框。您还可以将它们添加到自己的面板中,并重写面板的 setEnabled() 方法,以简单地启用/禁用复选框并更改标签的颜色。以这段代码片段为例:

final JCheckBox checkbox = new JCheckBox();
final JLabel label = new JLabel();
JPanel panel = new JPanel() {
    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        checkbox.setEnabled(enabled);
        if (enabled)
            label.setForeground(Color.BLACK);
        else
            label.setForeground(Color.GRAY);
    }
};
panel.add(checkbox);
panel.add(label);

请注意,checkbox 和 label 必须是最终的才能在面板的 setEnabled()` 方法中使用它们。根据您将 HTML 插入复选框的频率,您始终可以创建自己的组件类来执行此操作。

public class HTMLCheckBox extends JPanel {
    private JCheckBox checkbox = new JCheckBox();
    private JLabel label = new JLabel();
    private Color disabledColor = Color.GRAY;
    private Color enabledColor = Color.BLACK;

    public HTMLCheckBox(String text) {
        label.setText(text);
        add(checkbox);
        add(label);
    }

    public boolean isSelected() {
        return checkbox.isSelected();
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        checkbox.setEnabled(enabled);
        if (enabled)
            label.setForeground(enabledColor);
        else
            label.setForeground(disabledColor);
    }
}

然后根据需要添加您自己的构造函数和方法。例如,重写 setBackground() 以使其设置面板、复选框和标签的背景。更改标签文本的 setText() 方法可能也很方便。无论你想让它做什么。甚至可能还有 enabledColordisabledColor 的 setter ,允许您随意更改它们。

关于java - 如何复制 JCheckBox 的禁用外观?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3130650/

相关文章:

user-interface - Scala 和 Swing GUI 应用程序

python - Python 程序中的 'StringVar' 问题

java - JTextArea 中的行

java - 为什么我们需要 Scala 的 ParHashMap 而 Java 有 ConcurrentHashMap

java - 编写一个从 arraylist 返回迭代器的方法

Java 序列化 : readFields() beyond of readObject()?

java - 在JAVA中如何停止程序直到按下按钮?

java - 物理模拟,将像素调整为米?

.net - 是否有 WPF 控件可用于展开/折叠面板(动画)

java - 如何在JavaFX中绕点旋转三角形并获取点的值?