Is there a way to only mark a specific JPanel region as opaque?

565 Views Asked by At

Basically I'm drawing a lot of transparent JPanels; profiling shows that most time is spent in Component.paint(). It would be possible to optimize this quite radically since in most cases the real non-opaque area per JPanel is quite small, for example around the edges.

As it stands now, repainting() a component would trigger a repaint of all its parents, since the RepaintManager can't know the dirty parent area is in fact opaque and will go up the component hierarchy. I was thinking about calling markCompletelyClean() on all parents whenever a panel is invalidated and managing the dirty regions myself with addDirtyRegion().

However, is there a cleaner approach of marking only specific rectangles of a JPanel as opaque (or transparent, doesn't matter)?

3

There are 3 best solutions below

4
On BEST ANSWER

Even if you do something fancy with markCompletelyClean() and addDirtyRegion(), I doubt you'll get much of a performance benefit. When swing goes for a repaint, it collates all of the dirty regions to paint and starts a repaint with the minimum bounding box of all of the dirty regions. Thus if you mark the perimeter of a JPanel as dirty, then the bounding box of the JPanel is the same as the entire JPanel, which means you'll be repainting the entire thing any way.

1
On

Why can't you define your own method myRepaint() calling multiple

public void repaint(long tm, int x, int y, int width, int height)

for all the borders?

Also try to play with clipBounds of your Graphics to repaint only really necessary parts. You can set any custom Shape as clip.

1
On

Consider using JLabel (non-opaque by default) instead of JPanel, then you are able (to the JLabel) you can add any JComponent same as to the JPanel, but you have to set LayoutManager, then you forgot care about Opacity/Transparency and for particulars Region(s)