Reputation:
I tried to implement an automatic rolling progress-bar. The problem is that I can't stop it onece it starts. But It works fine when during the step by step debugging, and only during the debugging.
Here's a fragment of my codes. Any help will be highly appreciated.
package test;
import javax.swing.*;
public final class MyTest{
private boolean isvisible = false;
private JProgressBar progressbar = new JProgressBar();
/**
* thread of automatic rolling progress-bar
*/
private Thread proT = new Thread(new Runnable(){
@Override
public void run(){
isvisible = true;
progressbar.setVisible(true);
while(true){
progressBar.setValue((progressBar.getValue() + 20)%100);
System.out.println(progressBar.getValue());
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
if(!isvisible){
progressbar.setVisible(false);
break;
}
}
}
});
/**
* constructor
*/
public MyTest(){
//initiate GUI
}
/**
* show an automatic rolling progress-bar
*/
public void showProgressBar(){
proT.start();
}
/**
* stop/veil the progress-bar
*/
public void veilProgressBar(){
isvisible = false;
}
}
Upvotes: 0
Views: 68
Reputation: 41188
There are a whole raft of problems here:
You are doing Swing GUI updates from not on the EDT Thread.
Your isvisible variable is not volatile so changes made from one thread may not be seen from another.
While(true) sleep in a thread is generally bad design.
You should use a SwingTimer
here with a schedule to call back every X to do the update. When you need to stop the update just cancel the SwingTimer
and hide the control. The hide needs to be done from the EDT too though so you may need to do SwingUtilities.invokeLater
.
There may be more too but that's what I've seen so far.
Upvotes: 3
Reputation: 53462
AFAIK isvisible variable should be at least volatile
for other threads to be able to notice that it's been changed. You do no synchronization whatsoever so the value doesn't get updated.
Upvotes: 0