Over a million developers have joined DZone.

Swinging in Groovy is fun

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

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.

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

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

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

{{ parent.tldr }}

{{ parent.urlSource.name }}