Update JProgressBar from new theme
How can I update JProgressBar.setValue (int) from another thread? My second goal is to do this in the fewest possible classes.
Here is the code I have right now:
// Part of the main class....
pp.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
new Thread(new Task(sd.getValue())).start();
}
});
public class Task implements Runnable {
int val;
public Task(int value){
this.val = value;
}
@Override
public void run() {
for (int i = 0; i <= value; i++){ // Progressively increment variable i
pbar.setValue(i); // Set value
pbar.repaint(); // Refresh graphics
try{Thread.sleep(50);} // Sleep 50 milliseconds
catch (InterruptedException err){}
}
}
}
pp is a JButton and starts a new thread when the JButton is clicked.
pbar is a JProgressBar object from the main class.
How do I update its value? (progress)
The code above in run () cannot see pbar.
a source to share
Always follow the swing rule
Once a Swing component has been implemented, all code that may affect or depend on the state of that component must run on the event dispatching thread.
What you can do is create an observer that will update your progress bar, such as - in this case, you want to show the progress of data loading with one click of a button
DemoHelper
the class implements Observable
and sends updates to all observers when a certain percentage of the data is loaded. The progress bar is updated afterpublic void update(Observable o, Object arg) {
class PopulateAction implements ActionListener, Observer {
JTable tableToRefresh;
JProgressBar progressBar;
JButton sourceButton;
DemoHelper helper;
public PopulateAction(JTable tableToRefresh, JProgressBar progressBarToUpdate) {
this.tableToRefresh = tableToRefresh;
this.progressBar = progressBarToUpdate;
}
public void actionPerformed(ActionEvent e) {
helper = DemoHelper.getDemoHelper();
helper.addObserver(this);
sourceButton = ((JButton) e.getSource());
sourceButton.setEnabled(false);
helper.insertData();
}
public void update(Observable o, Object arg) {
progressBar.setValue(helper.getPercentage());
}
}
Shameless plugin: this is from a source from my demo project Feel free to browse through more details.
a source to share
You shouldn't do any Swing stuff outside of the event dispatch flow. To access this, you need to create a Runnable with your code running and then pass it to SwingUtilities.invokeNow () or SwingUtilities.invokeLater (). The problem is that we need a delay in the validation of the JProgressBar to avoid jamming the Swing thread. For this, we need a timer that will call invokeNow or later in its Runnable. Take a look at http://www.javapractices.com/topic/TopicAction.do?Id=160 for more details.
a source to share