How could I update content of several visible (at one time) components separately(independently) ? For example, I would like to show some kind of progress indicator with connected information, and it should only be updated/painted without painting all other components on form? Or if I have more then one components in progress and must update only their content.
-
1See if this previous [question](http://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint) helps. – Kavka Dec 05 '11 at 16:43
2 Answers
You can (and will have to, here) schedule your updates. You SHOULD NOT be running the long running calculation in the GUI thread (which appears unlikely, if you have a progress bar). But you still need to let the GUI know it needs to update... Something like so:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
// I didn't seem to see anything like this with a quick look-through.
// anybody else know differently?
public class ComponentUpdater implements ActionListener {
private static List<Component> componenets = new ArrayList<Component>();
public void addComponent(Component component) {
componenets.add(component);
}
@Override
public void actionPerformed(ActionEvent arg0) {
for(Component component : componenets) {
component.repaint();
}
}
}
And to use it, you need a timer:
UpdatingComponent componentToUpdate = new UpdatingComponent(dataSourceToExamine);
panel.add(componentToUpdate);
ComponentUpdater updater = new ComponentUpdater();
updater.addComponent(componentToUpdate);
Timer schedule = new Timer(500, updater);
timer.setRepeats(true);
timer.start();
This will cause every component added to the updater to have repaint()
caller ever 500 milliseconds, forever.
There are of course much more elegant ways to do this (like being able to specify update location), but this is a simple one to get you started.

- 12,806
- 6
- 31
- 45
-
So, as has been writted above, calling `repaint` on `Component` will lead to updating only this exact `component`? And even if this component is drawn "below" another component? Below some layer or below `GlassPane` content for example? – Yegoshin Maxim Dec 05 '11 at 17:34
-
1That component, including sub-components, only, will be updated. For instance, if you have a `JFrame` with two `JPanel`s: putting the `JFrame` in would cause everything to be updated. Putting only one of the `JPanel`s in would cause that one to be updated, but not the other. Please note that `repaint()` may still be called at 'random' intervals (whenever the GUI thread feels like it). – Clockwork-Muse Dec 05 '11 at 18:06
Whenever you call the repaint function (or one of your methods such as setText calls it for you) the component will repaint itself and all other components inside itself. In order to just repaint one thing, just call the repaint() method of that particular component. This will save memory and be much more predictable.
So in an example with a JProgressBar
JFrame frame = new JFrame("Title");
JPanel panel = new JPanel();
JProgressBar pBar = new JProgressBar(SwingConstants.HORIZONTAL, 0, 100);
panel.add(pBar);
frame.add(panel);
pBar.repaint(); // Will only repaint the progress bar
You can also repaint only a specific section of your program. So assuming the progress bar is located at (100, 100) and is 100 wide and 20 tall:
frame.repaint(new Rectangle(100, 100, 100, 20));

- 653
- 3
- 12
-
2You should not call `repaint();` let the progress bar update itself when the model has changed. – Jonas Dec 05 '11 at 16:50