Reputation: 1439
JPanel.setBackground
method does nothing (although opaque
attribute is true
) if super.paintComponent
father method isn't being called.
I have read a lot of similar questions here about this issue, and in each one of them I've only found solutions without explanation that helped me to understand why setBackground
method when written before adding the JPanel
to JFrame
changes the JPanel
background color, while when the setBackground
is written inside paintComponent
nothing is changed (only when calling father's paintComponent
method as already mentioned).
Is it somehow related to Graphics
object?
I have tried to change JPanel
's opaque
attribute to true
and using setBackground(COLOR.BLACK)
in paintComponent()
method I had overriden in a class that extends JPanel
paintComponent(Graphics g)
{
this.setOpaque(true);
this.setBackground(COLOR.BLACK);
}
I expect that the JPanel
background color will be black
Instead, background color is the default one
Upvotes: 1
Views: 455
Reputation: 11153
Well, first of all if you're using paintComponent(Graphics g)
method, the first line you need to have inside is: super.paintComponent(g)
otherwise you're breaking the paint-chain.
This will allow the parent component to draw the default component, before any customizations you do to it. If you don't do it, well, is like having a drawing in a piece of paper, imagine a circle, then cutting that circle and then trying to paint the outside.
Here's a more in-depth answer to How does super.paintComponent(g)
works
However I wouldn't write
this.setOpaque(true);
this.setBackground(COLOR.BLACK);
inside the paintComponent(...)
method, as it gets called several times and you can't control when it will ever get called. I would put those lines in a constructor, unless you want to change it later in your program while it's being painted depending on the state of your program or a gradient maybe.
For this part:
why setBackground method when written before adding the JPanel to JFrame changes the JPanel background color
Honestly, I don't understand what you mean.
Why do you say that if i won't call super.paintComponent(),it will break the chain? It's still drawing all the shapes and lines i want using graphics object.
From the docs:
The JPanel
has a UI delegate which performs the background painting for itself. You call it by using super.paintComponent(g)
and we pass the Graphics
component to prevent irrevocable changes such as Graphics.translate
Your JPanel
knows how to paint its children, but requires some help to paint itself, and this help comes from its parent.
When I mentioned "break the paint chain" I didn't mean nothing would paint, but that you would get strange behaviors such as the one of the JPanel
's background disappearing or not being set.
In addition,something weird happens if the argument i'm sending to setBackground method is a random color(using Random object). JPanel changing color very quickly although i'm not doing anything(not minimizing,not resizing,etc).Can you consider why?
As I said before, the paintComponent
gets called several times and you don't have control over when it will be called, even moving your mouse or something else will trigger the panel to repaint.
Upvotes: 2