I have a JProgressBar that I need to set a new minimum
, maximum
and progress
value each time a task of a queue is done, using the code below:
this.progressBar.setMinimum(minimum);
this.progressBar.setMaximum(maximum);
this.progressBar.setValue(progress);
But, I noticed that sometimes, the setMaximum(int)
method doesn't seems to work, because the progress bar still working with the old maximum value.
Then I wrote some test code and ran it:
progressBar.setMaximum(10);
System.out.println(progressBar.getMaximum());
Sometimes it prints 10
as expected, and sometimes prints the old value: anything different from 10.
I spent hours on Google and javadocs, tried to call revalidate()
and repaint()
on JProgressBar's parent, and nothing. I also tried to call Thread.sleep(10)
to wait AWT threads to run another tasks and didn't work.
Any ideas?
EDIT: Provided some more code:
/* Applet that construct the view and init a Thread. */
public class FastApplet extends Applet {
private JProgressBar progressBar;
private JPanel panel;
private Runnable runnable;
@Override
public void init() {
try {
java.awt.EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
createAndShowGUI();
initThreads();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void createAndShowGUI() {
panel = new JPanel();
progressBar = new JProgressBar();
progressBar.setStringPainted(true);
panel.add(progressBar);
}
private void initThreads() {
runnable = new MyRunnable(progressBar);
Thread thread = new Thread(runnable);
thread.start();
}
}
/* Runnable that update progress and call setMaximum(int) on JProgressBar */
public class MyRunnable {
private int progress;
private final JProgressBar progressBar;
MyRunnable(JProgressBar progressBar) {
this.progressBar = progressBar;
}
@Override
public void run() {
// do the tasks and update the progressBar using progressBar.setValue(progress)
// when done, reset the progress bar with the a new maximum:
defineNewProgressBar(0, 0, newMaximum);
}
public void defineNewProgressBar(int progress, int minimum, int maximum) {
this.progress = progress;
Component component = progressBar.getParent();
JPanel panel = (JPanel) component;
this.progressBar.setMinimum(minimum);
this.progressBar.setMaximum(maximum);
this.progressBar.setValue(progress);
panel.revalidate();
panel.repaint();
}
}
You wrote in your comments that you call setMaximum()
not from the EDT. You should call it from the EDT like this:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressBar.setMaximum(10);
}
});
If you use Java8, you can do this with using a lambda expression:
SwingUtilities.invokeLater(()->progressBar.setMaximum(10));