I'm trying to understand JButton
behavior. When I am adding a button to JFrame
with FlowLayout
layout, then the button is displayed with some blue color, although when I call button.getBackground
, I see that it returns a gray color (exactly the same RGB color as the JFrame
-container background). I read that there is a method getContentAreaFilled
that is also influence the button color.
If I set the contentAreaFilled
to false, I really get a gray button.
But,I also noticed that if I set button background to whatever color, then ContentAreaFilled
color doesn't matter anymore. I want to understand how does it work? Why when the background color isn't changed (setBackground
method isn't being called for button) the contentAreaFilled
color is dominant over the background button color, and when JButton
is set, the background is dominant over the contentAreaFilled
color.
Also setOpaque(false)
method influence the button background color only if setBackground
method was called, else setOpaque(false)
doesn't do nothing and only ContentAreaFilled
is matter
public class ButtonTest extends JFrame
{
public static void main( String[] args )
{
JButton justButton= new JButton("Just a Button");
// justButton.setBackground(Color.GREEN); //this line is critical
System.out.println("Button color is:"+ justButton.getBackground()+"\n");
ButtonTest frame= new ButtonTest();
frame.setLayout(new FlowLayout());
frame.add(justButton);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 275, 110 ); // set frame size
frame.setVisible( true ); // display frame
System.out.println("Frame background is:"+frame.getBackground()+"\n");
System.out.println("getContentPane color
is:"+frame.getContentPane().getBackground()+"\n");
System.out.println(justButton.isOpaque()+ " " +
justButton.isContentAreaFilled());
}
}
I expect that JBbutton
color will be gray (with the default value of JButton
background color) if I don't set button background differently.
Also I expect that setOpaque
method will influence JButton
background to be transparent, regardless of setBackground
method calls
The reason you are observing a "blue" color to your button is because of a gradient or other effect added by the pluggable look-and-feel (PLAF) in use. The color is actually grey, but the gradient makes it look blue. I'm guessing you are using the Metal PLAF, which has this effect.
If you replace the button's UI by a non-PLAF UI:
justButton.setUI((ButtonUI)BasicButtonUI.createUI(justButton));
then the button will keep the default color without having to use setBackground
or setContentAreaFilled
.
The reason calling setBackground
has the effect of removing the gradient or other special effect is because individual LAFs deal differently with background colors. The Metal LAF removes the effect altogether. The windows system LAF practically ignores the background color, and only shows a thin border with the color. Note the documentation of JComponent.sebBackground
:
It is up to the look and feel to honor this property, some may choose to ignore it.