You can't really blame Stu for it, he is surely more of server/web developer than a desktop one so he probably wasn't aware of the guidelines, he took the code from a JRuby example, which most likely was taken from somewhere else. The real problem is twofold
- bad programming examples since the early days of Swing.
- no way to enforce Sun's Swing guidelines at the compiler level (some tools may provide stricter checks)
In Java Swing you must always take extreme precautions regarding threading, one bad move and your app will appear to be unresponsive when doing a long-term computation, scaring the user away. Regular Swing applications will run from the main thread, thus leaving you the task to properly wrap your code with SwingUtilities. What does this have to do with JavaFx Script? there it happens the complete opposite. Every single JavaFx application runs inside the Event Dispatch Thread, always, period. This means you no longer have to worry about paint/repaint issues when changing UI state _but_ you still need to take care of long computations as they will be run inside the EDT. The following fx script demonstrates this fact
Once you jump out of the EDT you will eventually need to go back to update UI state. There is no current shortcut alternative for JavaFx (the jfx team is still working on it), so perhaps we shouldn't put away SwingWorker just yet. In case you are wondering you can't extend SwingWorker from JavaFx Script (at least not in a way I could find) given that it doesn't support generics declarations (yet). The alternative right now is pretty simple, drop down to the Java level, subclass SwingWorker and use it from your JavaFx scripts.
Now I'd like to show the Groovy alternative with a modified example, instead of displaying a dialog when the button is clicked, its text will change color from black to red and back
Once you run the example you'll get the following output
building ui inside EDT? true
Which means that SwingBuilder took care of properly building the UI inside the EDT, the static
build()
method runs on the EDT. Clicking on the button once yields the following outputaction handler inside EDT? true
long computation inside EDT? false
UI state change inside EDT? true
long computation inside EDT? false
UI state change inside EDT? true
Two methods should catch your attention:
doOutside
and doLater
. Those are handy threading abstractions provided by SwingBuilder. The first one spawns a new thread and runs the closure on it, the second one makes sure the closure is run inside the EDT. Simple, easy, Groovy. But if these threading facilities are not enough you can always subclass SwingWorker (in Groovy as it supports generics and other Java5 features) and plug it in.The road to JavaFx Script 1.0 is still ahead of us, the JavaFx platform continues to be under construction, expect some updates on threading, hopefully by the time 1.0 is released.
</rant>
Note: I do not posses any inside information on JavaFx, all this material is the result of my own explorations and blog posts around the web.