<< Down Votes on DZone Deserve Comments | Home | SwingBuilder: Integrating Groovy and Java >>

Groovy SwingBuilder Model Binding

I've been messing around with Groovy's SwingBuilder in my spare time. I did quite a bit of google-ing trying to figure out how to bind widget values to model properties. The example on the Groovy website wasn't very real world though it did get me pointed in the right direction.

After scanning the mailing list archives for quite a while I finally came up with a decent example of how to bind values from swing widgets to model properties. For this example I am creating a very simple login window. I put everything in a single groovy script to make this easy. Also note that I used MigLayout. While this works I wonder if this is best. I hope to hear from SwingBuilder enthusiast on my approach

import groovy.swing.SwingBuilder import net.miginfocom.swing.MigLayout import javax.swing.WindowConstants as WC class User { String username String password } def user = new User() def swing = new SwingBuilder() usernameTextField = swing.textField(columns:20) passwordTextField = swing.passwordField(columns:20) gui = swing.frame(title:'Login',defaultCloseOperation:WC.EXIT_ON_CLOSE) { panel(layout:new MigLayout('fill')) { label(text:'Username') widget(usernameTextField, constraints:'wrap, grow') label(text:'Password') widget(passwordTextField, constraints:'wrap, grow') button(text:'Login', constraints:'span', actionPerformed: { println user.username println user.password }) } } swing.bind(source:usernameTextField, sourceProperty:'text', target:user, targetProperty:'username') swing.bind(source:passwordTextField, sourceProperty:'text', target:user, targetProperty:'password') gui.pack() gui.show() .


Re: Groovy SwingBuilder Model Binding

Nice to see more postings on SwingBuilder, good example Gregg! here is an updated version (apologies if formatting messed the code)
import groovy.swing.SwingBuilder 
import net.miginfocom.swing.MigLayout 
import javax.swing.WindowConstants as WC 
 
class User { 
  String username 
  String password 
} 
 
def user = new User() 
 
SwingBuilder.build {
   frame(title:'Login', pack: true, show: true, defaultCloseOperation:WC.EXIT_ON_CLOSE) { 
      panel(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') 
}
Let's review the changes one by one. The first you may notice is that this example uses a static method build() to properly build the UI on the EDT. Frames in SwingBuilder understand two synthetic properties (pack,show), thus eliminating the last two explicit method calls. TextField and PasswordField are build inside the main closure, a (synthetic) id property is used to keep a reference in the SwingBuilder instance (created by the static build method and used as delegate). Lastly the bindings are created also inside the main closure, so that they may have access to the previous saved components. Benefits of this approach
  • the UI is built in the EDT (according to Sun's guidelines)
  • component references may be saved in the "build" scope
  • all UI related behavior is grouped in the build closure
In case you are wondering the build() method will return an instanceof SwingBuilder which is exactly the same used to build the UI, so if you save a components' reference (through an ide property) you can later access it using that instance and the id value as property name, i.e,
def swing = SwingBuilder.build{ frame(id:'f')}
swing.f.title = "Groovy!"
Cheers,
Andres

Re: Groovy SwingBuilder Model Binding

Thank you so much for this example and explanation. You answered a lot of lingering questions I had. I was using widget() to add the components because I read in order to have a reference to them they needed to be created outside of the ui code. Nice to know I can always get them via the ID.

Where would you say is the best source for this kind of information that is up to date?

Re: Groovy SwingBuilder Model Binding

I would say that the Groovy user list has a good set of golden nuggets, in the form of answers mostly written by Danno Ferrin (a.k.a shemnon), another good source would be GroovyConsoles's code. I'm afraid it is time we update/enhance the current SwingBuilder examples available at Groovy's site.

Re: Groovy SwingBuilder Model Binding

Thanks. I just started messing around with GraphicsBuilder. Now that is some super cool stuff as well

MigLayout

Hi could you please elaborate on the use of MigLayout? I am coming back from Java 1.2 and am wondering about which LayoutManager would be best to use... thx

Re: Groovy SwingBuilder Model Binding

I can't do anymore for MigLayout that their website doesn't already do. I am learning as I go at the moment so I wouldn't be able to speak about it one way or another. I only mentioned it in my article because it was a non-groovy API.

Add a comment Send a TrackBack