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:

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]