SwingWorker Example using publish() Method

This section provides a tutorial example on how to use java.swing.SwingWorker class with the publish() method to send out intermediate values from the doInBackground() method. The process() method must be implemented to catch those intermediate values in the dispatch thread.

Example 2: Publish intermediate values and catch them - This example shows the another way of using the SwingWorker class to just publish intermediate values while performing the background task and catch them result in the Dispatch thread. Only 2 methods need to be implemented:

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

/* SwingWorkerUsingPublish.java
 * Copyright (c) 2014, HerongYang.com, All Rights Reserved.
 */
import javax.swing.SwingWorker;
import java.util.List;
import java.util.Random;
import java.time.LocalTime;
public class SwingWorkerUsingPublish 
   extends SwingWorker<Object, Integer> {
   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());
            publish(n);
            i++;
         }
      } catch (Exception e) {
      	 e.printStackTrace();
      }
      logMessage("doInBackground() ended");
      return null;
   }
   
   protected void process(List<Integer> v) {
      logMessage("process() receiving values: "+v.size());
   }
   
// Launching my extended SwingWorker class
   public static void main(String[] a) {
      try {
         SwingWorker worker = new SwingWorkerUsingPublish();
         dumpThreads();
         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);
   }
}

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 SwingWorkerUsingPublish

22:50:44.146 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]

22:50:44.186 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[SwingWorker-pool-1-thread-1,5,main]
22:50:44.196 SwingWorker-pool-1-thread-1: doInBackground() started
22:50:44.236 AWT-EventQueue-0: process() receiving values: 4
22:50:44.286 AWT-EventQueue-0: process() receiving values: 5
22:50:44.336 AWT-EventQueue-0: process() receiving values: 5

22:50:44.386 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    22:50:44.386 AWT-EventQueue-0: process() receiving values: 5
Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
22:50:44.436 AWT-EventQueue-0: process() receiving values: 5
22:50:44.486 AWT-EventQueue-0: process() receiving values: 5
22:50:44.536 AWT-EventQueue-0: process() receiving values: 5
22:50:44.586 AWT-EventQueue-0: process() receiving values: 5

22:50:44.596 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]
22:50:44.636 AWT-EventQueue-0: process() receiving values: 5
22:50:44.686 AWT-EventQueue-0: process() receiving values: 5
22:50:44.736 AWT-EventQueue-0: process() receiving values: 5
22:50:44.786 AWT-EventQueue-0: process() receiving values: 5

22:50:44.796 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]
22:50:44.836 AWT-EventQueue-0: process() receiving values: 5
22:50:44.886 AWT-EventQueue-0: process() receiving values: 5
22:50:44.936 AWT-EventQueue-0: process() receiving values: 5
22:50:44.986 AWT-EventQueue-0: process() receiving values: 5

22:50:44.996 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]
22:50:45.036 AWT-EventQueue-0: process() receiving values: 5
22:50:45.086 AWT-EventQueue-0: process() receiving values: 5
22:50:45.136 AWT-EventQueue-0: process() receiving values: 5
22:50:45.186 AWT-EventQueue-0: process() receiving values: 5

22:50:45.196 Thread dump:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    22:50:45.196 SwingWorker-pool-1-thread-1: doInBackground() ended
Thread[SwingWorker-pool-1-thread-1,5,main]
    Thread[AWT-Shutdown,5,main]
    Thread[AWT-Windows,6,main]
    Thread[AWT-EventQueue-0,6,main]
22:50:45.236 AWT-EventQueue-0: process() receiving values: 1

22:50:45.406 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]

22:50:45.606 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 publishing intermediate values inside the doInBackground() method, and using the process() method to catch them:
SwingWorker Threads using publish() Method

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