10

我正在尝试以JToggleButton可靠、外观和感觉独立的方式选择 a 的颜色。

如果使用 Metal L&F,那么使用 UIManager 是一种方法:

UIManager.put("ToggleButton.selected", Color.RED);

注意:Iyy 指出我在上面的属性名称中有错字,但我会将其留在上面以供到达这里的人使用,但实际的属性名称应该是:

UIManager.put("ToggleButton.select", Color.RED);

但是,这在我当前的外观(当前是 Windows XP)中不起作用。经过进一步分析,Windows(仍然是 XP)中的系统外观似乎根本不使用任何Color基于- 的UIManager属性ToggleButton,或者至少它自己不提供它们(网上有一个快速示例可以找到中的所有属性键UIManager,在示例中方便地明确限制为Color属性)。

我试过设置背景颜色:

Action action = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) { /* stuff */ }
};
JToggleButton button = new JToggleButton(action);
// tried with and without opaque true
button.setOpaque(true);
button.setBackground(Color.RED);

它不仅不会改变选中状态,甚至不会影响未选中状态。

我只在收到操作后尝试更改背景颜色:

@Override
public void actionPerformed(ActionEvent e)
{
    JToggleButton button = (JToggleButton)e.getSource();
    if (button.isSelected()) // alternatively, (Boolean)getValue(Action.SELECTED_KEY)
    {
        button.setBackground(Color.RED);
    }
}

这些都不起作用。我发现唯一可以工作的事情需要我自己在选定状态下绘制按钮(这导致了一个工作示例,尽管看起来不标准):

private class ColoredToggleButton extends JToggleButton
{
    ColoredToggleButton(Action action, Color color)
    {
        super(action);

        setBackground(color);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (this.isSelected())
        {
            int w = getWidth();
            int h = getHeight();
            String s = getText();

            // selected color
            g.setColor(getBackground());
            g.fillRect(0, 0, w, h);
            // selected foreground color
            g.setColor(SystemColor.controlText);
            g.drawString(s,
                         (w - g.getFontMetrics().stringWidth(s)) / 2 + 1,
                         (h + g.getFontMetrics().getAscent()) / 2 - 1);
        }
    }
}

这是根据此Java 错误报告中的评论稍作修改的。有趣的是(有趣的是?),声称已在 1998 年修复。

有谁知道设置选定 JToggleButton 的背景颜色的更好的、独立于 L&F 的方法?

4

6 回答 6

8
JToggleButton btn = new JToggleButton(...);
btn.setUI(new MetalToggleButtonUI() {
    @Override
    protected Color getSelectColor() {
        return Color.RED;
    }
});
于 2014-03-30T03:07:17.093 回答
6

“ToggleButton.selected”是错误的,它需要“ToggleButton.select”。并且应该更新到组件。

UIManager.put("ToggleButton.select", Color.WHITE);
SwingUtilities.updateComponentTreeUI(togglebuttonname);
于 2013-03-05T04:38:50.540 回答
3

您可能会查看是否setIcon()足以满足您的目的,但您也可以paint()ButtonUI委托中覆盖。

附录:@kleopatra 的评论很受欢迎:更改 UI 委托并非易事。@mKorbel 最近的示例显示了该方法的难度和多功能性。它的基本优势是外观和感觉独立。

这里提到了一些不那么雄心勃勃的方法。

于 2011-04-27T17:52:09.997 回答
3

当它使用“Windows 外观”时;在 Netbeans 中,您只需要做两件事。

  1. 转到属性
  2. 取消选择“contentAreaFilled”
  3. 选择“不透明”
  4. 您可以在属性中或通过硬编码设置背景颜色

换一种方式,

    jToggleButton.setContentAreaFilled(false);
    jToggleButton.setOpaque(true);
    jToggleButton.setBackground(Color.red); //Your color here

就这样。:-)

于 2019-11-03T07:02:15.983 回答
1

您可以在每次重绘之前简单地强制背景颜色 - 为此您必须更改paintComponent,检查按钮是否被切换,根据切换状态设置背景,最后,让超类完成实际的绘画工作:

public class ColoredToggleButton extends JToggleButton
{
    @Override
    public void paintComponent(Graphics g)
    {
        Color bg;
        if (isSelected()){
            bg = Color.GREEN;
        } else {
            bg = Color.RED;
        }
        setBackground(bg);
        super.paintComponent(g);
    }
}
于 2016-11-25T11:29:27.343 回答
0

如果您更愿意使用操作侦听器而不是覆盖 UI 中的方法,您可以将 UI 更改为不带任何selectColor属性的 UI。

这是我最近使用的一个例子

private class FavouriteToggle extends JToggleButton {
    public FavouriteToggle() {
        setUI(new BasicToggleButtonUI()); //Removes selectColor

        ////Your Custom L&F Settings////
        setBackground(new Color(255, 252, 92));
        setForeground(Color.GRAY);
        setText("Favourite");
        setBorder(null);
        setFocusPainted(false);

        ////Add your own select color by setting background////
        addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(((JToggleButton) e.getSource()).isSelected()) {
                    setForeground(Color.BLACK);
                    setBackground(new Color(255, 251, 0));
                } else {
                    setBackground(new Color(255, 252, 92));
                    setForeground(Color.GRAY);
                }
            }
        });
    }
}
于 2016-12-01T14:13:01.790 回答