org.jpedal.utils.SwingWorker Maven / Gradle / Ivy
The newest version!
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/java-pdf-library-support/
*
* (C) Copyright 1997-2013, IDRsolutions and Contributors.
*
* This file is part of JPedal
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* SwingWorker.java
* ---------------
*/
package org.jpedal.utils;
import javax.swing.SwingUtilities;
public abstract class SwingWorker {
private Object value; // see getValue(), setValue()
// private Thread thread;
/**
* Class to maintain reference to current worker thread under separate synchronization control.
*/
private static class ThreadVar {
private Thread thread;
ThreadVar(Thread t) {
this.thread = t;
}
synchronized Thread get() {
return this.thread;
}
synchronized void clear() {
this.thread = null;
}
}
private ThreadVar threadVar;
/**
* Get the value produced by the worker thread, or null if it hasn't been constructed yet.
*/
protected synchronized Object getValue() {
return this.value;
}
/**
* Set the value produced by worker thread
*/
private synchronized void setValue(Object x) {
this.value = x;
}
/**
* Compute the value to be returned by the get method.
*/
public abstract Object construct();
/**
* Called on the event dispatching thread (not on the worker thread) after the construct method has returned
*/
public void finished() {}
/**
* 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 = this.threadVar.get();
if (t != null) {
t.interrupt();
while (t.isAlive()) {
try {
Thread.sleep(20);
}
catch (InterruptedException e) {
// tell user and log
if (LogWriter.isOutput()) LogWriter.writeLog("Exception: " + e.getMessage());
}
}
}
this.threadVar.clear();
}
/**
* Return the value created by the construct 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 construct method
*/
public Object get() {
while (true) {
Thread t = this.threadVar.get();
if (t == null) {
return getValue();
}
try {
t.join();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt(); // propagate
return null;
}
}
}
/**
* Start a thread that will call the construct method and then exit.
*/
public SwingWorker() {
final Runnable doFinished = new Runnable() {
@Override
public void run() {
finished();
}
};
Runnable doConstruct = new Runnable() {
@Override
public void run() {
try {
setValue(construct());
}
catch (Exception e) {}
finally {
SwingWorker.this.threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = new Thread(doConstruct);
this.threadVar = new ThreadVar(t);
}
/**
* Start the worker thread.
*/
public void start() {
Thread t = this.threadVar.get();
if (t != null) {
t.start();
}
}
}