Asynchronous Task inside the doInBackground() using java
Post date: Mar 29, 2011 12:19:39 PM
SwingWorker makes it easy to execute background tasks and report progress to the Event Dispatch Thread (EDT). Once on the EDT, your code can safely update GUI components like progress bars. This figure shows the general idea:
The general steps in my example are:
Extend the SwingWorker class.
Override doInBackground() to perform your background task.
While working, periodically call publish(...).
The SwingWorker will, in turn, periodically call process(...) on the EDT.
You can override process(...) to update the GUI as work proceeds.
You override done() to know when work completes. (or so you may think)
It turns out done() does not really work like that. Let’s look at some Java 6 code.
Sample Code
I’ll just present the entire application. This loops through fifty iterations in a background thread, pausing for random intervals between each iteration. It publishes the results and prints them to the console in the process(...) method. The done() method prints a message as well. Here it is:
public class Demo extends JFrame {
private Random rand = new Random();
private AbstractAction startAction = new
AbstractAction("Start") {
public void actionPerformed(ActionEvent e) {
startClicked();
} };
public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new Demo().setVisible(true); } }); }
public Demo() {
super("SwingWorker Demo"); add(new JButton(startAction), BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setLocationByPlatform(true); }
private void startClicked() {
startAction.setEnabled(false); new DemoWorker().execute(); }
private class DemoWorker extends SwingWorker<String, String> {
protected String doInBackground() throws Exception {
for (int i = 0; i < 50; i++) {
publish(Integer.toString(i));
TimeUnit.MILLISECONDS.sleep(rand.nextInt(25)); } return null; }
@Override
protected void process(List<String> chunks) { System.out.println("process: " + chunks); }
@Override
protected void done() { System.out.println("done."); startAction.setEnabled(true); } } }
Expected Output
Each time you run the program, you see slightly different results. That’s because publish(...) coalesces events and only calls process(...) “occasionally”. This is a really nice feature because it helps avoid bogging down the EDT. Here is the output:
process: [0, 1, 2, 3] process: [4, 5] process: [6, 7, 8] process: [9, 10, 11, 12] process: [13, 14, 15, 16] process: [17, 18, 19] process: [20, 21] process: [22, 23, 24, 25] process: [26, 27, 28, 29] process: [30, 31, 32] process: [33, 34, 35, 36] process: [37, 38, 39, 40, 41] process: [42, 43, 44] process: [45, 46] process: [47, 48, 49] done.
See? Just what we expected. Let’s run it again:
process: [0, 1, 2, 3] process: [4, 5] process: [6, 7, 8, 9] process: [10, 11, 12, 13] process: [14, 15] process: [16, 17, 18, 19] process: [20, 21, 22, 23] process: [24, 25] process: [26, 27, 28] process: [29, 30, 31, 32, 33] process: [34, 35, 36] process: [37, 38, 39] process: [40, 41, 42] process: [43, 44, 45] process: [46, 47] done. process: [48, 49]