alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

package org.jext.misc;

import javax.swing.SwingUtilities;

/**
 * This class comes from the SwingWorker class described at the URL below(3rd version), but has substantially changed;
 * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
 *
 */
public abstract class SwingWorker {
  private Object value;  // see getValue(), setValue()
  private Throwable exception;
  private Thread thread;
  protected HandlingRunnable notifier;

  /** 
   * Class to maintain reference to current worker thread
   * under separate synchronization control.
   */
  private static class ThreadVar {
    private Thread thread;
    ThreadVar(Thread t) { thread = t; }
    synchronized Thread get() { return thread; }
    synchronized void clear() { thread = null; }
  }

  private ThreadVar threadVar;

  /** 
   * Get the value produced by the worker thread, or null if it 
   * hasn't been constructed yet.
   */
  public synchronized Object getValue() {
    return value; 
  }

  /** 
   * Set the value produced by worker thread 
   */
  private synchronized void setValue(Object x) { 
    value = x; 
  }

  /** 
   * Get the value produced by the worker thread, or null if it 
   * hasn't been constructed yet.
   */
  public synchronized Throwable getException() {
    return exception; 
  }

  /** 
   * Set the value produced by worker thread 
   */
  private synchronized void setException(Throwable x) { 
    exception = x; 
  }

  /** 
   * Compute the value to be returned by the get method. 
   */
  public abstract Object work() throws Throwable;

  /**
   * Called on the event dispatching thread (not on the worker thread)
   * after the work method has returned.
   */
  public void finished() {
    if (notifier != null) {
      notifier.run(getValue(), getException());
    }
  }

  /**
   * A new method that interrupts the worker thread.  Call this method
   * to force the worker to stop what it's doing.
   */
  public void interrupt() {
    Thread t = threadVar.get();
    if (t != null) {
      t.interrupt();
    }
    threadVar.clear();
  }

  /**
   * Return the value created by the work method.  
   * Returns null if either the constructing thread or the current
   * thread was interrupted before a value was produced.
   * 
   * @return the value created by the work method
   */
  public Object get() {
    while (true) {  
      Thread t = threadVar.get();
      if (t == null) {
        return getValue();
      }
      try {
        t.join();
      }
      catch (InterruptedException e) {
        Thread.currentThread().interrupt(); // propagate
        return null;
      }
    }
  }


  /**
   * Create a thread that will call the work method
   * and then run 
   * 
   */
  public SwingWorker(HandlingRunnable notifier) {
    this.notifier = notifier;
    final Runnable doFinished = new Runnable() {
       public void run() { finished(); }
    };

    Runnable doConstruct = new Runnable() { 
      public void run() {
        try {
          setValue(work());
        } catch (Throwable t) {
          setException(t);
        }
        finally {
          threadVar.clear();
        }

        SwingUtilities.invokeLater(doFinished);
      }
    };

    Thread t = new Thread(doConstruct);
    threadVar = new ThreadVar(t);
  }

  /**
   * Start the worker thread.
   */
  /*public void start() {
    Thread t = threadVar.get();
    if (t != null) {
      t.start();
    }
  }

  /** Run the work in the calling thread, and then the notifier callback.*/
  /*public Object run() throws Throwable {
    Object o = null;
    Throwable t = null;

    try {
      o = work();
    } catch (Throwable th) {
      t = th;
      setException(t);
    }
    setValue(o);
    finished();
    if (t != null)
      throw t;
    return o;
  }*/
  public void start(boolean threaded) {
    Thread t = threadVar.get();
    if (t != null) {
      if (threaded)
	t.start();
      else
	t.run();
    }
  }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.