Reputation: 5533
For some UI components in our application, we override paintComponent
, which under some conditions "recursively" calls itself by invoking repaint
. We use this approach to achieve high refresh rate of animations in the component.
For instance, a progress bar we use looks something like:
public class SimpleProgressBar extends JPanel {
private boolean inProgress;
....
@Override
protected void paintComponent(Graphics g) {
if (inProgress) {
paintBar(g);
repaint();
} else {
doSomeOtherThings();
}
}
}
Is this a good practice (especially in terms of performance / efficiency / CPU usage)?
Is it better to use a Timer
or a background thread to repaint
our components?
Upvotes: 2
Views: 702
Reputation: 8348
Is this a good practice (especially in terms of performance / efficiency / CPU usage)?
No, it is not good practice. Calling repaint from within paintComponent
is bad practice because:
Is it better to use a Timer or a background thread to repaint our components?
Yes, using a Timer
or Thread
gives you much better control over the frame rate, without bogging down the EDT while doing so. Depending upon the context, a Timer
runs on the EDT (as opposed to a Thread) so no dispatching to the EDT is required.
Upvotes: 6
Reputation: 442
There are very few situations where overriding paintComponent
is a good thing. Your situation seems to be one of them; however, it is important to remember that it is not your job to call paintComponent
. What I mean by this, is that it is an office of the System to decide when to repaint certain components. This is especially evident when you drag the screen around, or when you put another screen over yours. That being said, it is very difficult to say how many times your method will be called; therein, making it difficult to say when it would be worth using that implementation.
On a side note, a background thread, as you put it, would more than likely not make it better, and Swing is notoriously not thread-safe.
I hope this helps, and best of luck to you!
Upvotes: 0