问题
I have a Java application which uses the native LAF like so:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
This is working great, however, I am trying to make a button have a red background, but ends up like this:

As you can see, I'm setting background and foreground on the button, but what results is not visually pleasing. Is there a way to have the button draw a red background without subclassing JButton?
回答1:
You must understand that under Swing's Look & Feel structure, it's the JButton's UI delegate that does its drawing, not the JButton itself, and so setBackground(...)
will not work well in this situation. You'll probably be better off adding an icon to the button instead.
回答2:
I created my own CustomColorButton with nice gradient end effects on click and mouse over which works under
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
You can create a new button like this:
CustomColorButton button = new CustomColorButton(Color.RED, Color.WHITE); // Background and font color
button.setText("Color button!");
The CustomColorButton class:
public class CustomColorButton extends JButton implements ActionListener, MouseListener
{
private boolean hovered = false;
private boolean clicked = false;
private Color normalColor = null;
private Color lightColor = null;
private Color darkColor = null;
public CustomColorButton(Color normalRedColor, Color fontColor)
{
setForeground(fontColor);
this.normalColor = normalRedColor;
this.lightColor = normalRedColor.brighter();
this.darkColor = normalRedColor.darker();
addActionListener(this);
addMouseListener(this);
setContentAreaFilled(false);
}
/**
* Overpainting component, so it can have different colors
*/
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
GradientPaint gp = null;
if (clicked)
gp = new GradientPaint(0, 0, darkColor, 0, getHeight(), darkColor.darker());
else if (hovered)
gp = new GradientPaint(0, 0, lightColor, 0, getHeight(), lightColor.darker());
else
gp = new GradientPaint(0, 0, normalColor, 0, getHeight(), normalColor.darker());
g2d.setPaint(gp);
// Draws the rounded opaque panel with borders
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // For High quality
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 7, 7);
g2d.setColor(darkColor.darker().darker());
g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 7, 7);
super.paintComponent(g);
}
@Override
public void actionPerformed(ActionEvent arg0)
{
System.out.println("Button clicked!");
}
@Override
public void mouseClicked(MouseEvent arg0)
{
}
@Override
public void mouseEntered(MouseEvent arg0)
{
hovered = true;
clicked = false;
repaint();
}
@Override
public void mouseExited(MouseEvent arg0)
{
hovered = false;
clicked = false;
repaint();
}
@Override
public void mousePressed(MouseEvent arg0)
{
hovered = true;
clicked = true;
repaint();
}
@Override
public void mouseReleased(MouseEvent arg0)
{
hovered = true;
clicked = false;
repaint();
}
}
回答3:
For anybody who comes along the problem I did, here's the solution I went with:
I switched to using an image added as a child of the button using ImageIcon:
BufferedImage stopPicture = null;
try {
stopPicture = ImageIO.read(new File("stop.png"));
} catch (IOException ex) { }
JLabel picLabel = new JLabel(new ImageIcon( stopPicture ));
JButton btnStop = new JButton("");
btnStop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SerialTest.getInstance().stopMoving();
}
});
btnStop.add(picLabel);
回答4:
If by "without subclassing" means without having to extend it yourself, then you have the option of using SwingX JXButton, that extends JButton to use painters (and more):
JButton button = new JButton();
button.setBackground(bg);
becomes
JXButton button = new JXButton();
button.setBackgroundPainter(new MattePainter(bg));
If you have to stick to the base JButton, I don't think there's a solution because of you the way L&F works.
来源:https://stackoverflow.com/questions/10973073/background-color-of-button-when-using-windows-laf