Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Swinging in Groovy is fun

DZone's Guide to

Swinging in Groovy is fun

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

There are several ways to create UI in Swing. Some people prefer writing the code by hand, some use graphical Swing designers instead. Groovy adds another possibility - the SwingBuilder. Leveraging the power of Groovy builders the SwingBuilder allows you to create UI by hand yet very efficiently.

To be concrete, here is a very simple Swing app written in Groovy, which automatically updates a label with whatever is in the text field. The example uses binding between Swing components.

JFrame frame = new SwingBuilder().frame(title: 'Binding sample',
defaultCloseOperation: JFrame.EXIT_ON_CLOSE) {
vbox {
JTextField valueToCalculate = textField()
label(text: bind(source: valueToCalculate,
sourceProperty: 'text',
converter: {it.toUpperCase()}))
}
}

I needed only 6 lines of self-explanatory code. What makes me more confident that this is a reasonable way to write Swing code is that the full power od Java-written Swing code is still at my fingertips. I can revert to plain Swing API any time for any parts of my code, like in the next demo, where I mix binding with classical Java or Groovy written KeyListener.

JFrame frame = new SwingBuilder().frame(title: 'Binding sample',
defaultCloseOperation: JFrame.EXIT_ON_CLOSE) {
vbox {
JTextField valueToCalculate = textField()
label(text: bind(source: valueToCalculate,
sourceProperty: 'text',
converter: {it.toUpperCase()}))
valueToCalculate.addKeyListener(new MyKeyListener())
}
}

Swing multithreading in Groovy

The SwingBuilder is also very effective when dealing with concurrency in Swing applications. Let say we need to perform a time-demanding db operation. May be, to retrieve some value from a db based on the value in a text field and show the result by updating the text of a label. We certainly have to invoke a separate thread to avoid freezing our UI and use SwingUtilities.invokeLater() to update the label with the result once we get it from the db. In Java we would need to create a new thread to run the retrieval and define a Runnable to update the UI. In Groovy we need only three lines of code to define the button and the operation, including all the multithreading boilerplate code. We leverage the doOutside() and doLater() methods, which create a new thread for communication with the db and update UI with the result inside the event queue thread respectively.

JFrame frame = new SwingBuilder().frame(title: 'Threading sample',
defaultCloseOperation: JFrame.EXIT_ON_CLOSE) {
vbox {
JTextField entityId = textField()
JLabel entityName = label(text: '')
button('Retrieve value from DB', actionPerformed:{doOutside{
def result = retrieveEntity(entityId.text)
doLater{entityName.text = result}
}})
}
}

The doLater() call assigns a UI update task to the event queue asynchronously. For synchronous call we can use edt() instead.

I guess that's pretty neat, isn't it? In my opinion, the SwingBuilder together with the GraphicsBuilder are very powerful tools, or DSLs if you like, for UI development on the Java platform.


This post originated at my blog - Swing binding and Swing multithreading in Groovy.

Download Modern Java EE Design Patterns: Building Scalable Architecture for Sustainable Enterprise Development.  Brought to you in partnership with Red Hat

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}