SwingWorker Example using "progress" Property

This section provides a tutorial example on how to use java.swing.SwingWorker class with the setProgress() method to update the 'progress' property value from the doInBackground() method. A PropertyChangeListener class must be implemented to catch the updated value of the 'progress' property in the dispatch thread.

Example 3: Update "progress" property and use it to show progress - This example shows you how to communicate the "progress" of a background task to a Dispatch thread. Only 1 method and 1 listener class need to be implemented:

Here is the source code of the example program, SwingWorkerUsingProgress.java:

/* SwingWorkerUsingProgress.java
 * Copyright (c) 2014, HerongYang.com, All Rights Reserved.
 */
import javax.swing.SwingWorker;
import java.util.Random;
import java.time.LocalTime;
import java.beans.*;
public class SwingWorkerUsingProgress 
   extends SwingWorker<Object, Object> {
   int total = 100;
   int wait = 10;

// Extending the SwingWorker class
   protected Object doInBackground() {
      logMessage("doInBackground() started");
      int i = 0;
      Random r = new Random();
      try {
         while (i<total) {
            Thread.sleep(wait);
            Integer n = new Integer(r.nextInt());
            setProgress((100*(i+1))/total);
            i++;
         }
      } catch (Exception e) {
      	 e.printStackTrace();
      }
      logMessage("doInBackground() ended");
      return null;
   }
   
// Launching my extended SwingWorker class
   public static void main(String[] a) {
      try {
         SwingWorker worker = new SwingWorkerUsingProgress();
         dumpThreads();
         worker.addPropertyChangeListener(new myListener());
         worker.execute();
         while (true) {
            dumpThreads();
            Thread.sleep(200);
         }
      } catch (Exception e) {
      	 e.printStackTrace();
      }
   }
   public static void dumpThreads() {
      System.out.println(LocalTime.now()+" Thread dump:");
      Thread.currentThread().getThreadGroup().list();
   }
   public static void logMessage(String s) {
      System.out.println(LocalTime.now()+" "
         +Thread.currentThread().getName()+": "+s);
   }
   static class myListener implements PropertyChangeListener {
      public void propertyChange(PropertyChangeEvent e) {
         if ("progress".equals(e.getPropertyName())) {
            logMessage("propertyChange() "+e.getNewValue()+"%");
         }
      }
   }
}

Notes on the sample program:

If you compile and run this example with JDK 1.8, you should get output messages similar to these:

C:\>java SwingWorkerUsingProgress

23:02:46.481 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]

23:02:46.521 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
23:02:46.531 SwingWorker-pool-1-thread-1: doInBackground() started
23:02:46.571 AWT-EventQueue-0: propertyChange() 4%
23:02:46.621 AWT-EventQueue-0: propertyChange() 9%
23:02:46.671 AWT-EventQueue-0: propertyChange() 14%

23:02:46.721 Thread dump:
23:02:46.721 AWT-EventQueue-0: propertyChange() 19%
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
23:02:46.771 AWT-EventQueue-0: propertyChange() 24%
23:02:46.821 AWT-EventQueue-0: propertyChange() 29%
23:02:46.871 AWT-EventQueue-0: propertyChange() 34%
23:02:46.921 AWT-EventQueue-0: propertyChange() 39%

23:02:46.921 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
23:02:46.971 AWT-EventQueue-0: propertyChange() 44%
23:02:47.021 AWT-EventQueue-0: propertyChange() 49%
23:02:47.071 AWT-EventQueue-0: propertyChange() 54%
23:02:47.121 AWT-EventQueue-0: propertyChange() 59%

23:02:47.121 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
23:02:47.171 AWT-EventQueue-0: propertyChange() 64%
23:02:47.221 AWT-EventQueue-0: propertyChange() 69%
23:02:47.271 AWT-EventQueue-0: propertyChange() 74%
23:02:47.321 AWT-EventQueue-0: propertyChange() 79%

23:02:47.331 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
23:02:47.371 AWT-EventQueue-0: propertyChange() 84%
23:02:47.421 AWT-EventQueue-0: propertyChange() 89%
23:02:47.471 AWT-EventQueue-0: propertyChange() 94%
23:02:47.521 AWT-EventQueue-0: propertyChange() 99%
23:02:47.531 SwingWorker-pool-1-thread-1: doInBackground() ended

23:02:47.531 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
23:02:47.571 AWT-EventQueue-0: propertyChange() 100%

23:02:47.731 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]

23:02:47.931 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]

Some interesting notes on the output:

The picture below gives you an idea on how the Launching thread, the Worker thread, and the Dispatch thread worked together in this example where I am repeatedly updating "progress" property value inside the doInBackground() method, and using a PropertyChangeListener class to catch it:
SwingWorker Threads using Progress Property

Last update: 2014.

Table of Contents

 About This Book

 Introduction of Java Swing Package

 Graphics Environment of the Local System

 JFrame - Main Frame Class

 JLabel - Swing Label Class

 JButton - Swing Button Class

 JRadioButton - Swing Radio Button Class

 JTextField - Swing Text Field Class

 Menu Bar, Menus, Menu Items and Listeners

 Creating Internal Frames inside the Main Frame

 Layout of Components in a Container

 LookAndFeel and UIManager

 Option Dialog Boxes

 JEditorPane - The Editor Pane Class

SwingWorker - The Background Task Worker

 What Is SwingWorker Class?

 SwingWorker Example using done() Method

 SwingWorker Example using publish() Method

SwingWorker Example using "progress" Property

 SwingWorker Example using JProgressBar

 References

 PDF Printing Version