package org.incha.ui.util;
import java.awt.SecondaryLoop;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.SwingUtilities;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.incha.ui.TaskProgressMonitor;
public final class ModalContext {
private static final Log log = LogFactory.getLog(ModalContext.class);
/**
* Default constructor.
*/
private ModalContext() {
super();
}
/**
* @param runnable
* @param fork
* @param progressMonitor
* @throws InterruptedException
* @throws InvocationTargetException
*/
public static void run(final RunnableWithProgress runnable, final boolean fork,
final TaskProgressMonitor progressMonitor)
throws InvocationTargetException, InterruptedException {
if (!fork) {
if (!SwingUtilities.isEventDispatchThread()) {
runnable.run(progressMonitor);
} else {
startModalContextThread(runnable, progressMonitor);
}
} else {
new Thread("Modal Context Tread") {
@Override
public void run() {
try {
runnable.run(progressMonitor);
} catch (final Exception e) {
log.error("Failed to run the runnable in modal mode", e);
}
}
}.start();
}
}
/**
* @param runnable the runnable to run.
* @param progressMonitor progress monitor.
* @param monitor the mutex for wait/notify operations.
*/
private static void startModalContextThread(
final RunnableWithProgress runnable,
final TaskProgressMonitor progressMonitor) {
final AtomicBoolean isExit = new AtomicBoolean(false);
final SecondaryLoop loop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
new Thread("Modal Context Tread") {
@Override
public void run() {
try {
runnable.run(progressMonitor);
} catch (final Exception e) {
log.error("Failed to run the runnable in modal mode", e);
} finally {
isExit.set(true);
loop.exit();
}
}
}.start();
//if not the modal thread i already finished, should itterupt it
if (!isExit.get()) {
loop.enter();
}
}
}