【问题标题】:Changing the background color of a selected JToggleButton更改选定 JToggleButton 的背景颜色
【发布时间】:2011-08-14 01:28:40
【问题描述】:

JToggleButton 以可靠、外观和感觉独立的方式被选中时,我正在尝试更改它的颜色。

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

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

注意:Iyy指出我在上面的属性名称中有错字,但我会把它留在上面让人们来到这里,但实际的属性名称应该是:

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

但是,这在我当前的外观(当前是 Windows XP)中不起作用。经过一些进一步的分析,Windows(仍然是 XP)中的系统外观似乎根本没有使用任何基于 ColorUIManager 属性用于 ToggleButton,或者至少它自己不提供它们(find all property keys from the 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 bug report 中的评论稍作修改。有趣的是(有趣的是?),声称已在 1998 年修复。

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

【问题讨论】:

  • 你可以覆盖 BasicbuttonUI 或只是 MetalButtonUI(然后只用于 Metal L&F)一些提示stackoverflow.com/questions/5751311/…
  • 为什么? LAF 应该控制外观,最好让它发挥作用 - 如果成功干扰,您的自定义油漆/颜色将像拇指一样突出
  • @kleopatra 我通常同意离开 L&F 是一种很好的做法,但简单地说,这是一个理想的功能。特别是,它实际上是为了突出。

标签: java swing custom-component uimanager jtogglebutton


【解决方案1】:
JToggleButton btn = new JToggleButton(...);
btn.setUI(new MetalToggleButtonUI() {
    @Override
    protected Color getSelectColor() {
        return Color.RED;
    }
});

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 这是一个很好的收获,这确实有效!但是,有一个相当大的警告,除非您创建自己的实例并为其提供新的static ComponentUI createUI(JComponent c),否则它会全局影响所有JToggleButtons。结果,我仍然坚持自己滚动,但对于那些想要全局更改背景颜色的人来说,你的方法是一个可行的解决方案。
    • 我太激动了,拼写错误是个好问题。但是,这不适用于 Windows 系统外观。
    • 进一步研究,似乎系统 L&F 甚至没有使用任何与 Color 关联的 ToggleButton 键(例如,“ToggleButton.background”)。
    【解决方案3】:

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

    附录:@kleopatra 的评论很受欢迎:更改 UI 委托不是微不足道的。 @mKorbel 最近的 example 显示了该方法的难度和多功能性。它的主要优势是外观和感觉独立。

    提到了一些不那么雄心勃勃的方法here

    【讨论】:

    • re:实现一个自定义的 ButtonUI/子类一个现有的 - 当然,一切皆有可能 - 但并非一切都是可行的 ;-) 我强烈的“不”。
    • @kleopatra:感谢您的评论;我试图从上面的角度来看待这一点。
    • @Jeanette 我一直很感激你在我的眼皮子里踢球,因为它总是关于(我的)poppycock 是什么,但 OP 可能不想听到它是不可能的,等待 BugsParade 的补丁,然后它往往会回复您 *** create CustomComponents,如果您对选项 setForeground 或 set Icon 不满意
    • 我扩展了BasicToggleButtonUI 并重新实现了绘制所有内容的逻辑,除了正确的背景颜色。然而,缺乏真正的可移植性(在我的 XP 主题中看起来都不错)使得它实际上毫无价值,尤其是考虑到显着增加的复杂性(就隐藏的错误而言),更不用说用户必须调用 toggleButton.setUI(myImpl)。我将保留我列出的最后一个选项(如果选择,则手动扩展和绘制),并希望 JDK 的未来版本实际上支持背景属性。它并不华丽,但可以完成工作。
    【解决方案4】:

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

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

    换一种方式,

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

    就是这样。:-)

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 对我不起作用。如果选择了按钮,Swing 不会使用提供的背景颜色。这适用于普通 JButton,但您必须自己实现选择/取消选择逻辑(这很容易)。
      【解决方案6】:

      如果您希望在 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);
                      }
                  }
              });
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-24
        • 1970-01-01
        • 1970-01-01
        • 2018-03-04
        • 2013-11-22
        • 1970-01-01
        • 2014-09-24
        相关资源
        最近更新 更多