I have a JFrame and following components.
JButton = jButton1
Progress Bar = progressBar and its public static
JLabel = status and its public static
When button clicks then different statements execute. I want to update my progressbar after each statement. Here is my code
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Task pbu = new Task(25, "Step 1....");
pbu.execute();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
pbu = new Task(50, "Step 2....");
pbu.execute();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
pbu = new Task(75, "Step 3....");
pbu.execute();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
pbu = new Task(100, "Done");
pbu.execute();
}
Here is my Task Class extended with SwingWorker
public class Task extends SwingWorker{
private int progress;
private String stat;
public Task(int pr, String st) {
progress = pr;
stat = st;
}
@Override
protected Object doInBackground() throws Exception {
NewJFrame1.progressBar.setValue(progress);
NewJFrame1.status.setValue(stat);
return null;
}
}
Any idea how can I solve this problem?
You don’t want to update GUI components off of the Swing thread.
SwingWorkerprovides hooks for doing stuff back on the Event Dispatch Thread, that’s what it’s designed for. Call thepublishmethod fromdoInBackgroundand overrideprocessto detail with incremental updates. Or, if you only need to update the GUI when it’s finished, override thedone()method.A very simple example:
Edit
@mKorbel makes a good point that for the above to work it needs to extend
SwingWorker<Void, Integer>…Voidbeing the overall return value type (in this case indicating there’s no return value) andIntegerbeing the type of the incremental updates.If the worker produces an actual final result (that will be retrieved with
get()) then that type can be used in place ofVoid. I had left out these details since I didn’t include the class declaration.See