Java - Difference between SwingWorker and SwingUtilities.invokeLater()
Asked Answered
P

2

11

SwingWorker is used for the following purposes:

  • For running long-running tasks in a different thread so as to prevent the GUI from being unresponsive
  • For updating GUI with the results produced by the long-running task at the end of the task through done() method.
  • For updating GUI from time to time with the intermediate results produced and published by the task with the help of publish() and process() methods.

SwingUtilities.invokeLater() can perform the above tasks as follows:

  • Instead of executing SwingWorker.execute() method from the EDT, we can execute ExecutorService.submit(new MyRunnable()) as it will also create another thread which can execute long-running task.
  • For updating GUI at the end of the task, we can put code (written in done() method of case1) SwingUtilites.invokeLater(new RunnableToExecuteDoneMethodCode()) at the end of the task.
  • For updating GUI in the middle of the task, we can put code (written in process() method of case1) SwingUtilites.invokeLater(new RunnableToExecuteProcessMethodCode()) at the place where we called publish() method in case1.

I am asking this question because the problem specified in question Java - SwingWorker - Can we call one SwingWorker from other SwingWorker instead of EDT can be solved by SwingUtilities.invokeLater() but can't be solved with SwingWorker

Palp answered 13/5, 2010 at 18:41 Comment(3)
I am not quite sure what the 'question' is.Osteal
@Osteal if you aren't sure, then leave it. Simple :)Palp
The problem you refer to is solvable by using SwingWorker. See my answer there.Potpie
A
7

SwingWorker is a helper class -- it is not that you need to use it, but using it is much simpler and clearer than doing the same work by hand. (It also makes checking progress easier.) Note that it was added version 6 -- before then some people used a simpler class defined in the Swing Tutorial or did step similar to the ones you noted.

Atmolysis answered 13/5, 2010 at 18:59 Comment(1)
+1 Conveniently, there's a source compatible back-port for Java 5. swingworker.dev.java.netCephalothorax
T
1

An important feature of the 1.6+ SwingWorker class is the EDT(Event Dispatch Thread) difference between doInBackground() and done(). You should think of doInBackground() as doWorkOutsideEDT() and done() as doWorkInsideEDT(). Run this instructional example to see the different.

    System.out.println("TID=" + Thread.currentThread().getId() + " (main)");
    final SwingWorker<String, String> x = new SwingWorker<String, String>() {
        @Override
        protected String doInBackground() throws Exception {
            final long tid = Thread.currentThread().getId();
            System.out.println("");
            System.out.println("TID=" + tid + " doInBackground() isEventDispatchThread=" + SwingUtilities.isEventDispatchThread());
            System.out.println("Long running code goes here.");
            return "";
        }

        @Override
        protected void done() {
            final long tid = Thread.currentThread().getId();
            System.out.println("");
            System.out.println("TID=" + tid + "          done() isEventDispatchThread=" + SwingUtilities.isEventDispatchThread());
            System.out.println("GUI updates/changes go here.");
        }
    };
    x.execute();
    x.get();

Output:

TID=1 (main)

TID=9 doInBackground() isEventDispatchThread=false
Long running code goes here.

TID=16          done() isEventDispatchThread=true
GUI updates/changes go here.
Tirza answered 16/5, 2014 at 14:3 Comment(1)
Wow! Your comment `` think of doInBackground() as doWorkOutsideEDT() and done() as doWorkInsideEDT()`` solved a month of beating my head against an exception updating a basic file browser JTable in a TransferHandler. Moved one line of code from doInBackground() to done() and it WORKS! Thanks for bringing that detail out.Perch

© 2022 - 2024 — McMap. All rights reserved.