« January 2007 | Main | March 2007 »

February 2007 Archives

February 2, 2007

Can We Get a Three State CheckBox in Java 7?

A lot of the blogging about swing has been about making things shiny, or spiffy, or even flashy. But how about adding some basic functionality that just about every look and feel except swing has: Three State CheckBoxes.

What kind of crazy talk is that? Check boxes are simple on-off switches, which can answer yes and no questions, like "I would like fries with that" and "Please send me spam." Yes, that is certainly the use case that check boxes were designed for, and by default should be how you could view them. But there are times where a simple yes or no could have yes and no, or and indeterminate answer. Major toolkits vary on how this is rendered,

Apple draws a dash:

At least one GTK theme draws a hash pattern

Windows Vista and XP draws a square:

The older Windows look draws a check with a hashed background:

Heck, even Version 3 of Cascading StyleSheets specifies and indeterminate checkbox! And they test for it too. (IE7 passes, Firefox fails, I'm just saying.)

There even exist written guidelines on how not to abuse them.

But wait, it gets crazier, if you dig into the XPStyle class of your src.zip (particularly in 5.0u8 or later) you will see that constants even exist for accessing the indeterminate checkbox. And it works, because I've done it.

So, is there anything that a lowly developer like me can do to get this into Java 7? I mean other than hack at the swing code when it is released and show how it is done. Doesn't it need some JSR to be worked under?

February 7, 2007

Groovy vs. Cocoa: invoking a method on the main GUI thread

Todd Ditchendorf compares Cocoa and Java and C# when it comes to acessing the GUI thread in their respective GUI toolkit. He ranks the readability as Cocoa then Java then C#.

Here is the Cocoa version, is this readable?

//... inside class definition ...

- (void)doStuffOnWorkerThread {
    // ... do worker thread stuff, then...
    id arg = ...
    [self performSelectorOnMainThread:@selector(doStuffOnMainGUIThread:)
                           withObject:arg
                        waitUntilDone:NO];
}

- (void)doStuffOnMainGUIThread:(id)arg {
    // update UI, etc...
}

If you are into brackets, self-referential code, name:value, operators as scope modifiers, and methods that look like e-mail addresses then Cocoa is for you. I prefer something more Groovy...

arg = ...

doInThread = {
   // update UI, etc...
}

SwingUtilities.invokeAndWait doInThread

Even groovier...

arg = ...

SwingUtilities.invokeAndWait {
   // update UI, etc...
}

February 14, 2007

Declarative GUIs in Java, Lysol for Code Smells

One of the complaints about Java Swing GUIs is not really about the platform per say. but is actually more about the tooling, standard or otherwise. The major lacking feature is a widely deployed declarative format for Declarative GUIs. This is pointed out quite clearly by one develper who left Java to code Cocoa apps.

It's not that there is a lack of a good GUI Design Tool. I could rave for days on end about NetBeans' Matisse builder and the new Group Layout. It provides for me a good balance between efficient visual layout and the ability to get into the code to tweak at it. The solution, guarded and non editable code blocks, was derided by Elliotte Rusty Harold as a code smell. I kind of have to agree with him.

So how do other platforms handle it? The C# portion of Visual Studio 2005 uses a new feature of C# called Partial Classes, basically it allows you to declare a class in two files. In the main file goes all of the user editable code and in a parallel file goes all the code that the GUI designer will smash, basically all the code that can go away after a billg or sjobs encounter.

Cocoa uses a different approach: via ".nib" files. These are generated by the Interface Builder tool that is a standard part of XCode or it's predecessor since, gosh, 1988. Yes, it's older than the GPL. So these ideas aren't exactly revolutionary or cutting edge.

The silly thing is, there is very little stopping NetBeans from adopting one of those two approaches, private access fields and methods not withstanding. They have an external data file (the .form file) that could either be read and executed dynamically (if needed fields are made public or it is granted privilege escalation to change access levels via reflection) or compiled to a parallel Foo$$Form.class file.

Such a declarative appeared last year on the roadmap, but the living document version has no such mention of it. What happened? Was this a reference to JDNC? I hope not, because JDNC is now defunct.

So, NetBeans Form team, any new guidance on the issue?

February 20, 2007

Groovy can save Swing

Groovy can save Swing. Well maybe, and maybe not. The real question in my mind is tools supporting Groovy Swing development. But for more of the substantive issues, Groovy can foot the bill. According to pinderkent JRuby cannot save Swing. This was a response to Julian Doherty's JRuby can save Swing, which itself was a response to an old post by Joshua Marinacci titled Swing has Failed. That's a lot of items to respond to, so for this post I will keep my comments to the first post, JRuby cannot save swing.

First, Kent brings up an oldie but a goodie, "Swing is Slow." At least he isn't pounding on Java is slow, that has academicaly been disproven years ago. The only problem left must be the API, and it is not the use of the API that makes many swing apps slow, but its abuse. The stock answer to this is always true: "bad programmers abuse the Event Dispatch Thread." Seriously, whenever anyone wants to start programming Swing someone else needs to get a stick and beat them until they write in blood the oath "I will not do data processing in the Event Dispatch Thread."

So how does Groovy make this simpler? It's closure syntax makes it less crufty to do things like process data in response to a button event. Check out one of my older posts on Groovy, Verbosity, and Swing to see how easy it is.

Kent's second argument is a red hearing. He complains about how difficult the swing API is. Let's look at another successful GUI toolkit: windows. We have the raw win32 APIs, then there is the MFC that got layered on top of that (or OWL if you are a Delphi fan) and then, yet another layer if you are up to date: WinForms. Lots of ugly confusing layers and arcane code. Lots of APIs are not a symptom of a toolkit that has failed, quite the contrary in most cases. I'd say it's a sign of maturity, and of a toolkit that people have used and that has evolved. You want simple? Go write web pages, just don't do anything complex, like AJAX, or CSS support across multiple browsers, or... wait. That stuff is just as big and confusing as Swing! Take your straw man and go home already

Finally, why is Groovy so much better in my opinion than JRuby for Swing apps? It's all about the syntax. Groovy looks like Java 95% of the time. In fact almost all Java code snippets can be dropped into a Groovy script without alteration. JRuby? You need to learn a new syntax, and ugly PERLisms like conditionals after statements. i.e. format_drive unless drive_has_useful_data, the problem being the "unless" portion can scroll off the right of your text editor so you can never see it. Swing programmers are used to seeing C based Java Code, and almost all Java code drops into Groovy quite nicely.

But none of this will matter unless we get better IDE support for Groovy. Sure, there is an eclipse plug-in for Groovy and Grails, and NetBeans has Coyote. But JetBrains has gone Ruby on Rails crazy and NetBeans is going down that path as well for NetBeans 6.0. It appears that tool support, and not completion of the JSR, will be Groovy's Alamo.

February 21, 2007

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();
frame.add(buttonPanel);

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

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setVisible(true);

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!

February 26, 2007

Swing Can Find Salvation in Groovy

With all of this talk about saving Swing, perhaps we missed the connotation it should be taken in. Saved as in "being born again" or a transcending [linguistic] experience. Perhaps we have strayed away from the notion of people running around with their Bibles shouting at each other something to the effect of "My religion is better than yours." Since that was basically what happened to the Swing vs. SWT dialog I can see how we would all put up our mental blinders.

But the implication I like from the "Saved" is the part about trancendance, I mean that in and of it self sounds kinda groovy. A dynamic language can open up a whole new plane of understanding to swing that wasn't available in static languages. But along with any other change sometimes it has a cost. The problem with religion, is that generally speaking they require an exercise of faith, with doesn't really address the concerns of doubt, it (for lack of several paragraphs) ignores it most of the time.

For example, there are some things that a dynamically typed language, by definition, cannot address. One of those is type-safe enumerations. While Groovy can turn on some type safety when explicitly stated, the implementation of the SwingBuilder really cannot guarantee that at compile time. Not only that, but since Groovy 1.0 runs on a 1.4 era JVM, it cannot reliably use the typesafe enums that debuted in Java 5.0.

There are also issues related to swing that will never be related to which toolkit you use. One of those is the concern that it renders slow, even on old hardware. I can tell you from extensive personal experience that if you hammer out all of the work you do in the Event Dispatch Thread you can make your application run just fine on a circa 2001 Dell Laptop with a 900MHz Pentium 4 processor with only 256Mib of Memory. I know because that was the reference machine I did a lot of my GUI work on in a previous life, and I removed almost all of the grey boxing from the GUI at the behest of the QA fascists (very skilled QA fascists if you must ask). And I did most of it with a debugger attached, on a 1.4.2 JVM to boot. But that's the problem with religion: even if you make it easy some people will still go their old ways, oblivious to the sin they commit. Making a Swing GUI spin like a top is truly a labour of love, ask the coders at JetBrains, they can tell you. And it's not restricted to Swing, making a quality GUI is always a matter of attention to detail. what changes between GUI toolkits is which details you have to look at.

Finally, there are some things that getting religious about Groovy can address. One of those is the leakage of package contents from java.awt to javax.swing. For example, how would you use a Grid Layout and a Box Layout in the same panel without importing different packages? Like this:

import groovy.swing.SwingBuilder

frame = new SwingBuilder().frame {
  gridLayout(rows:2)
  label("Code in Groovy?")
  panel {
    boxLayout()
    button("Yes")
    button("Ahhh  Yeahhh!")
  }
}
frame.pack()
frame.show()

Because the Swing Builder is a total replacement for the traditional way of hand assembling the swing frames, we can remove some of the layering issues. There are also a lot of other things that can be done, but it may take a while before the better practices become mainstream.

But that does always seem to be the problem with religions, they can often be separated into two groups: the group the Methodists belong in and then the group Moonies belong in. Religions that got mainstream acceptance and those that didn't. It is still too early to decide if this dynamic language fervor (in general, not just for Swing) will cross the chasm or fall into it.

About February 2007

This page contains all entries posted to ... And They Shall Know Me By My Speling Errors in February 2007. They are listed from oldest to newest.

January 2007 is the previous archive.

March 2007 is the next archive.

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

Powered by
Movable Type 3.33