« Groovy can save Swing | Main | Swing Can Find Salvation in Groovy »

Groovy can give Swing a fresh start

Looks like the Swing debate is catching fire in Java Blog land, not that anyone is throwing keroscene on the fire or anything. Well daniel at DZone makes an excellent point: Does Swing Need Saving? He's right. Swing isn't dieing, it is the #1 GUI Toolkit in development in IT shops today. However, it sure could use a fresh start, kind of like windows got with .NET and the WinForms API (and like it got with MFC before that).

One of the points he tries to hammer in on is that dynamic languages may simply be a solution looking for a problem. To illustrate that he makes a simple 3 button form in Java, and then proceeds to do the same in JRuby. How would that look in Groovy?

import javax.swing.*
import java.awt.*

JFrame frame = new JFrame("Test Frame");

JLabel label = new JLabel("This is the header");
label.setFont(label.getFont().deriveFont(label.getFont().getSize2D() + 10 as Float));
frame.add(label, BorderLayout.NORTH);

JPanel buttonPanel = new JPanel();

buttonPanel.add(new JButton("Button 1"));
buttonPanel.add(new JButton("Button 2"));
buttonPanel.add(new JButton("Button 3"));

frame.setSize(400, 200);

Basically you strip out the containing main class and method and drop it right into Groovy. There is one quirk on line 7 where you need to cast a double down to a float, because Groovy defaults floating point operations to double precision. No biggie really. However, this only reinforces the point he was making, it really doesn't make things any cleaner. If only there was a Groovier way to Swing...

import javax.swing.*
import java.awt.*

swing = new groovy.swing.SwingBuilder()

frame = swing.frame(defaultCloseOperation : JFrame.EXIT_ON_CLOSE,
                                    title : "Test Frame",
                                     size : new Dimension(400, 200)
                    ) {
  label = label(text:"This is the header", constraints: BorderLayout.NORTH)
  panel {
      button("Button 1")
      button("Button 2")
      button("Button 3")
label.font = label.font.deriveFont(label.font.size2D + 10 as Float)
frame.visible = true

This, IMHO, does seem to be a bit cleaner, ant it looks a whole lot closer to that mythical declarative GUI layout that people have been talking about. And this also illustrates why I think Groovy is superior to plain old Java to breath new life into swing. (a) all your old tricks work and (b) it opens up new possibilities for use by dynamic languages. And this example doesn't even address one of the real banes of Swing development: the listener pattern. That is where Groovy and it's support of Closures and Function Pointers really sines, brother!

Comments (4)

Charles Nutter (headius) of JRuby proposes an almost identical toolkit: http://blogs.dzone.com/daniel/2007/02/21/does-swing-need-saving/#comment-10 It's really interesting, all three of us managed to want the same API simultaneously. :-)

Personally, I like the Ruby version better than the Groovy, but why quibble about syntax? Maybe one of us should prototype something to see how it goes...

Christian García:

Take a look at this opinion: It's not about a new sintax to write UIs. Java needs more inteligence. The complexity must stay inside Swing, but it must be transparent to users.


My comment was just based on a hypothetical swingbuilder in Ruby, but this fellow has actually implemented a pretty complete version that really looks impressive. It even includes support for binding properties...


The amazing thing about this is how little Ruby code was needed...and no Java code at all.

Danno Ferrin [TypeKey Profile Page]:

Thanks to jola_zm at DZone for the link to Swing being the #1 toolkit.

Post a comment


This page contains a single entry from the blog posted on February 21, 2007 8:33 PM.

The previous post in this blog was Groovy can save Swing.

The next post in this blog is Swing Can Find Salvation in Groovy.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33