I find it easiest to think of setOpaque this way:
setOpaque( false ) means I
want my canvas cleared prior to each paintComponent
where setOpaque( true )
means I want it left the way it was from the last paintComponent. Even when you setOpaque
( true ), super.paintComponent will clear your
canvas to the background colour to start.
JComponent.setOpaque
( boolean ) is misnamed. It really should be called
JComponent. wipeBackground(
Boolean ). When you setOpaque( true ), Swing wipes the
background to the component’s background colour before calling your
paintComponent method. This replaces the
AWT (Advanced Windowing Toolkit) update/ paint mechanism.
- You would set setOpaque( false ) if you want what is behind your component to bleed
through, e.g. if you were drawing a round button.
- You would set setOpaque( true ) if you wanted nothing to show through — you wanted
unpainted parts of your component to appear as the background colour.
- For efficiency, even if you had an opaque component, you might setOpaque ( false ) when your
paintComponent method painted every single pixel, so
there was no background to show through. There is no point in clearing the
background before painting.
setOpaque usage
setOpaque Usage |
setOpaque(?) |
call super.paintComponent
in paintComponent? |
Meaning |
false |
|
There is no point in doing this. |
false |
|
You will paint only some of the pixels or use some transparent pixels to
deliberately let what is painted underneath show through. |
true |
|
You paint every pixel of the region, with no transparent pixels and you
want Swing to clear the region to the background colour for you
automatically. |
true |
|
You paint every pixel of the region, with no transparent pixels and you
will clear the background as needed with clearRect
yourself in your paintComponent method. |
The symptom of failing to call setOpaque( true ) is flicker, where the image gets repeatedly repainted
to the background colour. The symptom of calling setOpaque(
true ), when you should not are artifacts —
little bits of left over painting from other work in where your component should be.
These are areas you did not paint, which should have been background.
If in your TableCellRenderer you create your own
JLabels to return, rather than using the one from
DefaultTableCellRenderer, make sure you call JLabel.setOpaque( true ) or else your
JLabel.setBackground will be ignored.
Sometimes the results you get from setOpaque and
calling super. paintComponent defy logic. Just try all possibilities and take the
one that works.