Alexander's answer catches the most important points regarding your questions.
This answer provides some supplemental information.
When does the JavaFX event dispatcher thread throw an exception and when not ?
The JavaFX system does not always check that accesses to objects affecting the active scene graph are properly restricted to the JavaFX thread. Ultimately, ensuring such thread safety is the responsibility of the JavaFX application programmer - not the JavaFX system. You must be very careful when performing multi-threaded programming in JavaFX, otherwise application behaviour may fail or become unpredictable.
Are the any good documents about this
Try the the JavaFX tutorial: Concurrency in JavaFX.
Is there an easier (shorter & cleaner) way to use Platform.runLater with a run() method?
No. Platform.runLater
is as simple as it gets.
As an aside . . .
Task and Service
Consider using the Task or Service subclasses of Worker. These are JavaFX wrappers for FutureTask (which is in turn a Runnable). Workers provide a call method to run logic on a background thread. They maintain execution status (with thread safe callback notification to the JavaFX thread for state changes) and return results of the call via value, message and exception properties.
Take advantage of the design patterns in the Task
and Service
javadoc examples to simplify creation of thread-safe applications with features such as:
- Asynchronous fetching of data for UI update.
- Periodic message updates for task progress.
- Constructing Node graphs which are not yet attached to a displayed scene.
- Monitoring progress via progress bars, etc.
A Worker
is complementary to Platform.runLater
. Use Platform.runLater
when you are executing off of the JavaFX Application Thread and you want to run some logic on the JavaFX application Thread. Use a Worker
when you are running on the JavaFX Application Thread and want to spawn some logic or (especially) I/O on a new thread so that you don't block the JavaFX Application Thread. You would never want to do network I/O inside a Platform.runLater
's run
method, but would often want to do it in a Worker
's call
method.
Also, usage of Task
and Service
is not incompatible with use of Platform.runLater
. For instance, if you have a very long running Task
from which you want to return partial results to the UI periodically or as a buffer fills, then executing Platform.runLater
in the task's call
method is the way to do that.
Workers are useful when you don't have an existing threaded service provided by a library, but are instead creating your own threads to execute in the background. If you have an existing threaded service, then you will need to use Platform.runLater
to perform logic on the JavaFX application thread.
Note that you still need to know what you are doing, even if you use a Worker
. You must still take care that you don't violate standard JavaFX concurrency rules, such as never updating Nodes on the active scene graph (including not updating values that Nodes in the active scene graph are bound to - such as the observable list of items backing a ListView).