invokeAndWait for JavaFX
#DataFX
#General
#JavaFX
Swing offers the two methods SwingUtilities.invokeAndWait(...)
and `SwingUtilities.invokeLater(…) to execute a Runnable object on Swings event dispatching thread. You can read more about this methods http://javarevisited.blogspot.de/2011/09/invokeandwait-invokelater-swing-example.html.
As I currently know JavaFX provides only Platform.runLater(...)
that is the equivalent of SwingUtilities.invokeLater(…). A “runAndWait” method doesn’t exist at the moment. While developing some [DataFX]({{ site.baseurl }}{% link pages/projects/datafx.md %}) stuff and my first Raspberry Pi demo I needed this feature in JavaFX. So I created a runAndWait
method that will hopefully be part of DataFX in some future. Until then you can use this code in your project:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javafx.application.Platform;
public class FXUtilities {
private static class ThrowableWrapper {
Throwable t;
}
/**
* Invokes a Runnable in JFX Thread and waits while it's finished. Like
* SwingUtilities.invokeAndWait does for EDT.
*
* @param run
* The Runnable that has to be called on JFX thread.
* @throws InterruptedException
* f the execution is interrupted.
* @throws ExecutionException
* If a exception is occurred in the run method of the Runnable
*/
public static void runAndWait(final Runnable run)
throws InterruptedException, ExecutionException {
if (Platform.isFxApplicationThread()) {
try {
run.run();
} catch (Exception e) {
throw new ExecutionException(e);
}
} else {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
final ThrowableWrapper throwableWrapper = new ThrowableWrapper();
lock.lock();
try {
Platform.runLater(new Runnable() {
@Override
public void run() {
lock.lock();
try {
run.run();
} catch (Throwable e) {
throwableWrapper.t = e;
} finally {
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
});
condition.await();
if (throwableWrapper.t != null) {
throw new ExecutionException(throwableWrapper.t);
}
} finally {
lock.unlock();
}
}
}
}
It’s working for all my needs. Please give me some feedback if there are any problems or bug.
Hendrik Ebbers
Hendrik Ebbers is the founder of Open Elements. He is a Java champion, a member of JSR expert groups and a JavaOne rockstar. Hendrik is a member of the Eclipse JakartaEE working group (WG) and the Eclipse Adoptium WG. In addition, Hendrik Ebbers is a member of the Board of Directors of the Eclipse Foundation.