« February 2007 | Main | April 2007 »

March 2007 Archives

March 13, 2007

Groovy SwingBuilder and Bindings, a Hole to be Filled.

Groovy's Swing support is good, but can be improved. Julian Doherty has pointed out that there is currently no Groovy way to do data binding to GUI elements. In reality this is more of a problem with Swing/Java than with Groovy. But in my estimation it's not that there aren't enough ways to do binding, it's that there isn't a Groovy way to do bindng.

I hate to be the Knight who says "NIH" but all of the existing frameworks don't quite have the needed groove. JGoodies Binding, for example, has really nifty stuff including buffered updates and complex list editing support. But according the the author there is a steep learning curve and it is best suited when one person can master the classes. JFace is best suited for SWT programming.

The up and coming binding framework is JSR-295. However, I think it will suffer from one horrible crippling detail, dependance on the Expression Language, intially developed for JSP. You know, I was part of the expert committee for JSP when the EL was introduced. My role? Sitting there with my eyes closed and my fingers in my ears singling "LALALALA" and hopeing it would go away. It didn't. But my reluctance to embrace 295 for Groovy binding is not that I feel EL is a red headed step child only fit for the web tier (only a slight exaggeration). But my feeling is that if we are going to do things like property type conversions, validation, and complex declarations of which properties are going to be bound is that such things should be done with closures, not another interpreted text string. But since an API review still has yet to be released, it is unknown whether it is suitable to be used under the covers or not.

If I had to do it what would I do? I would likely build a new Builder: BindingBuilder. Why not build it into swing? First, binding may be useful outside the context of GUI Widgets, like JavaBeans events are currently modeled. Second, if you read the specs multiple binding templates can be defined in groups and applied in a pick and choose fashion to groups of elements, making it one to one with a SwingBuilder makes that hard. Third, we can add it as a related class to SwingBuilder by creating one if needed by adding magical methods, like is done for all of the widgets currently.

Next, I would build the binding off of a single core flow: First some trigger is tripped (either via event or explicitly). Then, values are read from the source, via some closure friendly means. Next the inbound data is massaged in some closure friendly means. At this step the binding can be aborted if the massaging logic says so. Finally, if the massager likes it, we will apply it to some target via a closure friendly means. If it sounds a lot like how the JavaOne Slides describe JSR-295 it is meant to, with some closure friendly means and a whole lot less statically typed interfaces.

Finally, I would write a boat load of convenience methods in the builder mapping common patterns to the single core flow. Property syncs are easy. Bi-directional syncs are on by default, but can be turned off by a property in the builder. Table selections, column selections, list to table mappings. All of this done with the aim to reduce typing when you write the code. Less typing of the keyboard and less typing of the objects, let the binding builder do that for you.

March 23, 2007

New to Swings? Sshhh... Don't Tell Anyone Sun's Secret!

You can tell Kirill is not on Sun's payroll, since he didn't get the memo to be quiet about any leaking of swings. Charles Ditzel isn't saying boo about it, and neither is Romain Guy. Luckily the only NDAs I've signed with sun relate to the JCP so I can spill the beans.

Think of it this way -- http : https :: swing : swings. SwingS is the new Secure Swing extensions that Sun is throwing together to support rendering of high quality swing GUIs via HDCP connections. Apparently the MPAA didn't like that you can not only get the Swing source code from Sun (and soon via GPL) but even if the source code wasn't released one could very easily decompile the code. And don't expect to see source code, the licencing body of the HDCP keys doesn't like anything that isn't opaque, if there is the slightest bit of transparency they will freak out. I mean, you should have seen the conniption their reps threw the first time they saw the Aero Glass effect at Microsoft. They said such transparency was "Un-American" so Steve Balmer said "fine, we'll only release it in EMEA and Asia" (but obviously the relented).

Well, I'm releasing way too many industry secrets (and by secrets I mean totally made up stuff) so I should stop.

March 28, 2007

Late Binding is Swell, Late Typing is Groovy!

One of the major changes introduced late in the process of releasing Groovy 1.0 was the addition of the Meta-Object-Protocol or MOP. (Well, late is relative, considering it took 2-3 years to release Groovy 1.0 adding something 4 months from the end is late). One of the biggest features of the MOP is how it does the late bindings to the relevant Groovy methods based on type. This is best illisrtated by an example (who's output will be at the end of the post)...

class MOP_is_Groovy {
  void late(Float f) {println "Float!"}
  void late(Integer i) {println "Integer!"}
  void late(Number n) {println "Number?"}

  void earlyDef(def d) {late(d)}
  void earlyNumber(Number n) {late(n)}

t = new MOP_is_Groovy()
i = new Integer(2)
f = new Float(2)
n = new Long(2)

println "defs"

println "types"

What this example is doing is hiding the possible typing of the objects deeper into the class than a compiler would know at the surface level. If each of the calls to the early methods were instead direct calls to the late methods then the compiler could statically determine which of the particular late methods to call. But when hidden behind an intervening method the compiler cannot determine which one to call later because strictly speaking it doesn't know which one it will call later, because the method may be overridden by a sub class.

Groovy, however, whey applying a method call in a groovy script uses the MOP to look up the methods and finds one with the closest type at the time of invocation. When earlyDef is passed in an Integer, it uses the MOP to determine that it should call the Integer variant of late, and similarly with a Float. However, when a class is passed in that doesn't have an exact type match Groovy needs to find the signature that has the least distance from the passed in types. This example is rather tricky, because the implicit conversions for built in types takes precedence over trying to fit it into a parent type. A Long is closer to a Float than it is it's parent type of Number, simply because of these rules. If I had uses new types it would call the Number variant.

In order to be consistent Groovy applies the MOP even when the type at runtime can be constrained to a specific type, in this case lateNumberstill uses the MOP even though it knows that what is passed in must be a Number (it could also be an Integer or a Float as well). So how do you explicitly over-ride the MOPs choice of methods? Use Groovy's as operator to explicitly set the type at call time...

println "casted"
t.late(i as Number)

And as promised, the output of these scripts




March 29, 2007

Why Would a Groovy Swing Programmer Need a Matisse-like GUI Builder?

Geertjans been doing great things with Groovy and NetBeans.

Given how easy this all is in Groovy, I wonder whether the Groovy community even needs a Matisse-like GUI Builder. It all seems pretty intuitive, and with syntax coloring and code completion, plus maybe one or two other fun things (such as the Navigator shown above), coding Swing in Groovy is going to be a breeze.

Why would someone writing a GUI in Groovy need a Matisse-like GUI Builder? Layout. Specifically GroupLayout.

You can stop reading this blog entry here if you get it. I'm not likely to add anything informative to the Visual GUI Builder debate in this post. But in the end it's the same reason most people don't open up a text editor and write postscript and instead fire up Microsoft Wurd or something. (Can mis-spelling a word keep me from copyright infringement? We shall see.). Some things are just easier to see in a 2-D WYSYWIG format than in an essentially one dimensional coded representation of the same.

Geertjan's sample is deceptively simple. Why the widgets are nicely centered and separated is because the default layout of a Panel is FlowLayout. This is only really useful for simple GUI demonstrations and nested button panels anyway. What if you are doing an address form where the labels are all left aligned and the text fields all need to fill the same width (which is for most to the right edge of teh form), except for the checkbox on row 4 for suite number and the text field it enables below it (which needs to be indented and aligned with the checkbox text) and line 8 which is a North American 3-3-4 telephone number in separate text boxes, and all text labels and text boxes need to be baseline aligned, except for the action buttons that need to anchor to the south east on this resizable dialog. Oh, and follow the spacing guidelines from the Java Look and Feel as well.

This example may sound contrived, but it's not. Try codeing that by hand. Actually don't, I'm against self-inflicted pain. Boot up Netbeans, and use Matisse and the new Group Layout.

About March 2007

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

February 2007 is the previous archive.

April 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