问题
I have a custom UI for certain buttons, implemented by subclassing MetalButtonUI. The buttons use HTML-formatted labels. This is a requirement for me, I need to support multiline button labels.
For some reason, when my application runs on Java 7 (scientifically update 4, the most current) the text color when the button is disabled is now grey. This does not happen when running on Java 4 or 6.
In the HTML for the button label, I can set the font color by using <font color=..>
However this value is ignored when the button is disabled. It seems like somewhere, my font color is overridden when the button is disabled. Using <body style='color: ..'>
is also ineffective.
I've tried setting Button.disabledText in UIDefaults. This isn't what I really want to do because it affects too many buttons. But in any case it isn't effective for HTML formatted button labels.
MetalButtonUI defines getDisabledTextColor, but implementing it is not effective.
Similarly, implementing the paintText method is not effective. It is not invoked for HTML-formatted labels.
I could override the entire paint method but that seems like an overly complex solution.
There was a bugfix in this area, reported fixed in Java 7, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4783068 The bug report isn't very clear to me however. It isn't clear what specifically was changed, or how to override the new behavior.
Does anyone know how to control the text color for disabled buttons?
EDIT: Sorry I should have included example code from the get-go. My original code had custom classes for the button and for the UI, with custom paint() methods in the UI class. But I now see that the core problem can be demonstrated very simply, with just a call to button.setForeground(Color.black); In Java 6 this affects the text color for both enabled and disabled states. In Java 7 it affects only the enabled state. mKorbel ... thank you for helping isolate the problem!!!!
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();
}
});
}
}
Edit #2: this is now tracked as a bug by Oracle, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7176683
回答1:
Does anyone know how to control the text color for disabled buttons?
one of the way (you meant Html) is



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();
}
});
}
}
回答2:
I read the bug report that you posted on your question and they provided a workaround that will solve this issue. Create the below class:
/**
* 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"));
}
}
}
Then add it to your JToggleButton like so
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());
来源:https://stackoverflow.com/questions/10954597/java-7-color-of-button-text-when-using-html-formatted-labels