Java Swing developers are well aware of the golden Swing Rule. Given that it's so easy to break it we at Griffon try to make your life easier by sticking to conventions.
As a developer, you'd like to write code like this
The Model is somehow bound bidirectionally to the View, which means every change made to the View is propagated to the Model and vice-versa. The searchInterwebz action is most likely tied to a button, which means it will be invoked in the same thread that dispatched the event; that's right, that would be the EDT. Reading information from the Model is safe as long as it's done in the same thread that updated it (the EDT). Writing back to the model should be done inside the EDT as well. However querying the network and processing the results are tasks that must be performed outside of the EDT or we risk scaring users away as we just broke the Swing Rule.
Since the early days of Griffon we advocated the usage of edt{}, doLater{} and doOutside{} to properly identify blocks of code that must be executed inside a particular thread. The previous code can be rewritten like this
Much better. We've made explicit the fact that querying the network should be done outside of the EDT and that updating the back the model should be done inside the EDT. If the application we're writing requires only a handful of actions then this coding style is good enough. However it can get out of hand and probably tiresome to apply the same mechanics to a bigger set of actions. Considering that most of the actions may react to an UI event and most likely execute a computation that must be run outside of the EDT ... couldn't we figure out a convention that covers most cases? That's precisely what Griffon 0.9.2 did. Since that version, Griffon assumes that all controller actions must be invoked outside of the EDT. It applies some byte code manipulation magic (well, it's just AST manipulation really) to wrap each action with doOutside{}, like so
Good! However there's one slight problem with this approach. We now have to make sure the action explicitly updates the model inside the EDT -- that's why we wrapped the call with edt{}. What now?
Let's trace back to what we know and what Griffon should be aware given that it compiles our code. The enabled property of the model is bound to an UI component, probably in the this wayOK, so Griffon knows the particulars of that binding. It knows that the button's enabled state will change whenever the Model's enabled property is updated. Couldn't it figure out a way to transparently update the UI inside the EDT as well? It turns out now it can.
Griffon 0.9.4 was just released today. It includes Groovy 1.8.2 containing a new feature described by GROOVY-4962. Basically what this feature does is figure out the correct thread to use when updating a binding depending on the type of beans used in the binding. You're now able to rewrite the Controller code in this way
- the action will be invoked outside of the EDT automatically, as if wrapped by doOutside{}.
- model updates will be sent in the same thread as the caller (a non-EDT thread), however for listeners that have ties to UI elements (like the binding) the notification will be sent inside the EDT.
How's that for code clarity and brevity? In the case these conventions get in your way know that you can disable or configure them to your needs.
Keep on Groovying!