1

I've got a separate thread which needs to request some data that may change in the meantime within the JavaFX thread. I'd like to execute a blocking invocation in this separate thread that makes sure that the request becomes enqued into the JavaFX thread.

The Swing-GUI testing framework, AssertJ, provides an easy to use API for this purpose:

List list = GuiActionRunner.execute(new GuiQuery<...>...);

The invocation blocks the current thread, executes the passed code within event dispatching thread and returns the required data.

How can this be implemented in production code for JavaFX applications? What would be the recommended approach for this requirement?

PAX
  • 1,056
  • 15
  • 33

2 Answers2

7

Here's an alternative solution, using a FutureTask. This avoids the explicit latch and managing the synchronized data in an AtomicReference. The code here is probably simple enough that it would make including this functionality inPlatform redundant.

FutureTask<List<?>> task = new FutureTask<>( () -> {
    List<?> data = ... ; // access data 
    return data ;
});
Platform.runLater(task);
List<?> data = task.get();

This technique is very useful if you want to pause a background thread to await user input.

Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Hint: The JavaFX `Task` extends `FutureTask` so you can reuse existing Tasks and call `.get()` on them. – eckig Jan 01 '15 at 17:02
2

Ok I think I got it now. You need to implement something like this yourself:

AtomicReference<List<?>> r = new AtomicReference<>();
CountDownLatch l = new CountDownLatch(1);
Platform.runLater( () -> {
    // access data
    r.set(...)
    l.countDown();
})
l.await();
System.err.println(r.get());
tomsontom
  • 5,856
  • 2
  • 23
  • 21
  • 1
    If you want to make the code very slightly cleaner, you can avoid the explicit use of a latch by executing a `FutureTask` in `Platform.runLater(...);`. – James_D Jan 01 '15 at 15:54
  • There will never be blocking APIs like this in fx because it's easy to produce deadlocks - efxclipse runtime does have API like this - see http://git.eclipse.org/c/efxclipse/org.eclipse.efxclipse.git/tree/bundles/runtime/org.eclipse.fx.ui.services/src/org/eclipse/fx/ui/services/sync/UISynchronize.java – tomsontom Jan 01 '15 at 16:17
  • @James_D see the API we have at efxclipse i think this is the way to go – tomsontom Jan 01 '15 at 16:18