SwingBuilder: Integrating Groovy and Java
Today's SwingBuilder excursion revolves around the fact that I am developing a Swing application where Groovy isn't being used at all. What I realized was that while I can't say for certain if SwingBuilder really makes complex forms easier to write I do know that simple forms are far simpler in SwingBuilder than vanilla Swing.
I started with the same script from my last post and modified it according to Andres' suggestions as well as only building a panel rather than starting with a frame. I've already got a JFrame so what I needed was a simple way to build form panels. I also provided a method to get the panel which will be an instance of a JPanel object.
import groovy.swing.SwingBuilder
import net.miginfocom.swing.MigLayout
class User {
String username
String password
}
def user = new User()
swing = SwingBuilder.build {
panel(id:'loginPanel',layout:new MigLayout('fill')) {
label(text:'Username')
textField(id:'usernameTextField', columns: 20, constraints:'wrap, grow')
label(text:'Password')
passwordField(id: 'passwordTextField', columns: 20, constraints:'wrap, grow')
button(text:'Login', constraints:'span', actionPerformed: {
println user.username
println user.password
})
}
bind(source:usernameTextField, sourceProperty:'text', target:user, targetProperty:'username')
bind(source:passwordTextField, sourceProperty:'text', target:user, targetProperty:'password')
}
def getLoginPanel() {
return swing.loginPanel
}
In my existing Swing code I used the scripting API in Java 1.6 to evaluate the script and get the panel. I then added the panel to a JDialog. I've omitted boilerplate code and try/catch for brevity.
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine engine = m.getEngineByName("groovy");
engine.eval(new FileReader("scripts/LoginPanel.groovy"));
Invocable inv = (Invocable) engine;
JPanel result = (JPanel)inv.invokeFunction("getLoginPanel");
dialog.add(result)
The only real downside I see to this right now is the first time the groovy script is eval'd it takes roughly 5-8 seconds for it to complete and then I can see the form in the dialog. Without exiting the app subsequent requests are instantaneous.