1

我有一个特定按钮的自定义 UI,通过子类化 MetalButtonUI 实现。这些按钮使用 HTML 格式的标签。这是对我的要求,我需要支持多行按钮标签。

出于某种原因,当我的应用程序在 Java 7(科学更新 4,最新)上运行时,禁用按钮时的文本颜色现在为灰色。在 Java 4 或 6 上运行时不会发生这种情况。

在按钮标签的 HTML 中,我可以使用设置字体颜色<font color=..>但是当按钮被禁用时,这个值会被忽略。好像在某个地方,当按钮被禁用时,我的字体颜色被覆盖了。使用<body style='color: ..'>也是无效的。

我尝试在 UIDefaults 中设置 Button.disabledText。这不是我真正想做的,因为它影响了太多按钮。但无论如何,它对 HTML 格式的按钮标签无效。

MetalButtonUI 定义了getDisabledTextColor,但实现它并没有效果。

同样,实现paintText方法也无效。它不会为 HTML 格式的标签调用。

我可以覆盖整个绘制方法,但这似乎是一个过于复杂的解决方案。

该区域有一个错误修复,报告在 Java 7 中已修复,请参阅http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4783068但是错误报告对我来说不是很清楚。目前尚不清楚具体更改了什么,或者如何覆盖新行为。

有谁知道如何控制禁用按钮的文本颜色?

编辑:对不起,我应该从一开始就包含示例代码。我的原始代码有用于按钮和 UI 的自定义类,在 UI 类中有自定义的 paint() 方法。但我现在看到核心问题可以非常简单地演示,只需调用 button.setForeground(Color.black); 在 Java 6 中,这会影响启用和禁用状态的文本颜色。在 Java 7 中,它只影响启用状态。mKorbel ...感谢您帮助隔离问题!!!!

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.*;


    public class DisabledButtonDemo {


        public DisabledButtonDemo() {
            final JToggleButton button = new JToggleButton(
               "<html><center>Button<br/>Label</center></html>");      

            // Next line sets the text color. 
            // In Java 6 it is respected, for both enabled and disabled state.
            // In Java 7, it is only used for the enabled state.
            button.setForeground(Color.black); 
            button.setPreferredSize(new Dimension(100, 100));

            final JButton controlButton = new JButton(
               "Toggle Enabled/Disabled");
            controlButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    button.setEnabled(!button.isEnabled());
                }
            });

            JFrame f = new JFrame("ButtonTest");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLayout(new GridLayout(2,1));
            f.add(button);
            f.add(controlButton);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    DisabledButtonDemo t = new DisabledButtonDemo();
                }
            });
        }
    }

编辑 #2:这现在被 Oracle 跟踪为一个错误,请参阅http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7176683

4

2 回答 2

2

有谁知道如何控制禁用按钮的文本颜色?

一种方式(你的意思是Html)是

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class HtmlAndJButton {

    public HtmlAndJButton() {
        final String buttonText = " Whatever, but nothing wise";
        final JButton button = new JButton(buttonText);
        JButton btn1 = new JButton("Toggle");
        btn1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                button.setText("<html><font color=" + (button.isEnabled() ? "blue" : "red") + ">"
                + buttonText + "</font></html>");
                button.setEnabled(!button.isEnabled());
            }
        });
        JFrame f = new JFrame("ButtonTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(2,1));
        f.add(button);
        f.add(btn1);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                HtmlAndJButton t = new HtmlAndJButton();
            }
        });
    }
}
于 2012-06-08T19:52:59.173 回答
0

我阅读了您在问题上发布的错误报告,他们提供了解决此问题的解决方法。创建以下类:

/**
 * Attaches to a JButton to work around Sun bug 4783068.
 * <p>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4783068</p>
 */
public final class SunBug4783068Fixer implements PropertyChangeListener {

private static final SunBug4783068Fixer INSTANCE = new SunBug4783068Fixer();

public static void attach(AbstractButton to) {
    // Prevents adding it more than once to any single component.
    to.removePropertyChangeListener(INSTANCE);

    to.addPropertyChangeListener(INSTANCE);
}

public static void remove(AbstractButton from) {
    from.removePropertyChangeListener(INSTANCE);
}

public void propertyChange(PropertyChangeEvent evt) {
    if ((evt.getSource() instanceof AbstractButton)
         && "enabled".equals(evt.getPropertyName())) {
        AbstractButton target = (AbstractButton) evt.getSource();
        target.setForeground(target.isEnabled()
            ? (Color) UIManager.getDefaults().get("Button.foreground")
            : (Color) UIManager.getDefaults().get("Button.disabledText"));
    }
  }
}

然后像这样将它添加到您的 JToggleButton

 final JButton controlButton = new JButton("Toggle Enabled/Disabled");
        controlButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                button.setEnabled(!button.isEnabled());
            }
        });
 controlButton.addPropertyChangeListener(new SunBug4783068Fixer());
于 2012-06-12T15:41:12.200 回答