JProgressBar is not updated in a loop
I am currently learning Java. I've tried different things like JRadioButton
s, JcomboBox
es, etc. Now I am trying to use JProgressBar
, but it doesn't work as expected.
Relevant code snippet:
JProgressBar progress;
JButton button; //Fields of the class
progress=new JProgressBar(JProgressBar.HORIZONTAL,0,100);
button=new JButton("Done"); //Done from methods
progress.setValue(0);
progress.setStringPainted(true);
progress.setBorderPainted(true); //Also done from methods
button.addActionListener(this); //Also done from methods
On click, button
I want to show that the JProgressBar goes from 0% to 100%. Here's the relevant part of the method actionPerformed
:
public void actionPerformed(ActionEvent e)
{
for(int i=0;i<=progress.getMaximum();i++)
{
progress.setValue(i);
/*try{
Thread.sleep(10);
}catch(InterruptedException ex)
{
System.err.println("An error occured:"+ex);
ex.printStackTrace();
}*/
}
progress.setValue(progress.getMinimum());
}
I added the two progress
and button
to a JPanel and a panel JFrame, which I use setVisible(true);
.
The problem here is that whenever I click on the JButton the button
JProgressBar progress
does not go from 0% to 100%. Instead, nothing happens. If I uncomment the block try...catch
and then press button
, the program freezes for a moment and then continues. This time the JProgressBar stays at 0% and I never see it moving. I also tried repaint();
right after the block try...catch
, but the same thing happened.
I tried adding
System.out.println(i+"");
inside the loop for
in actionPerformed
, and these are printed numbers from 0 to 100 in the terminal. So I'm pretty sure the loop works.
How can I solve this problem?
source to share
-
Swing single-threaded,
-
all updates must be done on EDT,
-
all events in the current EDT are colored in the GUI in one moment,
-
Thread.sleep
to block the execution of an event in the EDT, redraw can be painted at the end of for_loop, after all the locks (s) from have beenThread.sleep
completed, more in Oracle trail - Compatibility in Swing and EventDispatchThread
output from AWT (Swing) Listener - ActionListener
, should be executed if all events inside actionPerformed
are executed, then only is executed progress.setValue(progress.getMinimum());
, it doesn't matter if it exists Thread.sleep
or not
public void actionPerformed(ActionEvent e) -> progress.setValue(progress.getMinimum());
-
use
SwingWorker
orRunnable#Thread
withprogress.setValue(i);
enclosed ininvokeLater
-
for better help post soon
SSCCE
/MCVE
, short, runnable, compilable
source to share
You have to put the following piece of code in a new thread
public void actionPerformed(ActionEvent e)
{
for(int i=0;i<=progress.getMaximum();i++)
{
progress.setValue(i);
/*try{
Thread.sleep(10);
}catch(InterruptedException ex)
{
System.err.println("An error occured:"+ex);
ex.printStackTrace();
}*/
}
progress.setValue(progress.getMinimum());
}
Something like that
public void actionPerformed(ActionEvent e)
{
new Thread(){
public void run(){
for(int i=0;i<=progress.getMaximum();i++)
{
progress.setValue(i);
try{
sleep(10);
}catch(InterruptedException ex)
{
System.err.println("An error occured:"+ex);
ex.printStackTrace();
}
}
}
}.start();
progress.setValue(progress.getMinimum());
}
Not tested, progress
copy should be final
possible
source to share
As far as your code is concerned, everything looks legal. Doesn't seem to give any problem regardless of whether or not the thread initiates.
I suggest you do this:
//for testing purposes
progress.setValue(progress.getMinimum());
And then make the progress bar value 50. Remove the thread code and use a for loop with the "<50" condition.
If all else fails, this will surely shed some light: JProgress Bar: Working!
Let me know about the results.
source to share