更改选定 JToggleButton 的背景颜色

发布于 2024-11-03 09:32:12 字数 2461 浏览 5 评论 0原文

当以可靠、外观和感觉独立的方式选择 JToggleButton 时,我试图更改它的颜色。

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

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

注意:Iyy 指出我在上面的属性名称中有一个拼写错误,但我会将其保留在上面以方便人们到达这里,但实际的属性名称应该是:

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

但是,这在我当前的外观和感觉(当前为 Windows XP)中不起作用。经过进一步分析,Windows(仍然是 XP)中的系统外观似乎没有使用 ToggleButton< 的任何基于 ColorUIManager 属性。 /code> 根本不存在,或者至少它本身不提供它们(在线有一个快速示例 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 年修复。

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

I am trying to change the color of a JToggleButton when it has been selected in a reliable, look and feel independent way.

If using the Metal L&F, then using the UIManager is an approach:

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

Note: Iyy pointed out that I had a typo in the property name above, but I will leave it above for people getting here, but the actual property name is supposed to be:

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

However, this does not work in my current Look and Feel (currently Windows XP). After some further analysis, it appears that the system look and feel in Windows (still XP) does not use any of the Color-based UIManager properties for ToggleButton at all, or it at least does not supply them itself (there is a quick example online to find all property keys from the UIManager, which in the example is conveniently limited explicitly to Color properties).

I have tried setting the background 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);

Not only does it not change the selected state, but that does not even effect the unselected state.

I have tried changing the background color only after receiving the action:

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

None of that works. The only thing that I have found to work requires me to draw the button myself in the selected state (which leads to a working example, albeit non-standard looking):

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);
        }
    }
}

That is slightly modified from a comment in this Java bug report. Interestingly (amusingly?), in claims to have been fixed in 1998.

Does anyone know of a better, L&F independent way to set the background color of a selected JToggleButton?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

李不 2024-11-10 09:32:12
JToggleButton btn = new JToggleButton(...);
btn.setUI(new MetalToggleButtonUI() {
    @Override
    protected Color getSelectColor() {
        return Color.RED;
    }
});
JToggleButton btn = new JToggleButton(...);
btn.setUI(new MetalToggleButtonUI() {
    @Override
    protected Color getSelectColor() {
        return Color.RED;
    }
});
池予 2024-11-10 09:32:12

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

UIManager.put("ToggleButton.select", Color.WHITE);
SwingUtilities.updateComponentTreeUI(togglebuttonname);

"ToggleButton.selected" is wrong, it require "ToggleButton.select".
And should be update to the component.

UIManager.put("ToggleButton.select", Color.WHITE);
SwingUtilities.updateComponentTreeUI(togglebuttonname);
用心笑 2024-11-10 09:32:12

您可能会看到 setIcon() 是否足以满足您的目的,但您也可以在 ButtonUI 委托。

附录:@kleopatra 的评论很容易理解:更改 UI 委托并非微不足道。 @mKorbel 最近的示例显示了该方法的难度和多功能性。它的本质优势是外观和功能。感到独立。

此处提到了一些不太雄心勃勃的方法。

You might see if setIcon() is sufficient for your purpose, but you can also override paint() in the ButtonUI delegate.

Addendum: @kleopatra's comment is well-taken: changing the UI delegate is not trivial. @mKorbel's recent example shows both the difficulty and versatility of the approach. Its essential advantage is look & feel independence.

Some less ambitious approaches are mentioned here.

云柯 2024-11-10 09:32:12

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

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

以其他方式,

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

仅此而已。:-)

When it using "Windows look and feel"; in Netbeans you have to do only two things.

  1. Go to properties
  2. Un-select 'contentAreaFilled'
  3. Select 'opaque'
  4. You can set a background color in properties or by hard coding

In other way,

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

That's all.:-)

幼儿园老大 2024-11-10 09:32:12

您可以简单地在每次重绘之前强制背景颜色 - 为此,您必须更改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);
    }
}

You can simply force background color before each repaint - for that you have to alter paintComponent, check if button is toggled, set background depending on toggle state and, at last, let super class do the actual paint job:

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);
    }
}
故笙诉离歌 2024-11-10 09:32:12

如果您更愿意使用操作侦听器而不是重写 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);
                }
            }
        });
    }
}

If you would rather use an action listener instead of overriding methods in a UI you can just change the UI to a UI without any selectColor properties.

Here is an example I used recently

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);
                }
            }
        });
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文