« December 2007 | Main | May 2008 »

April 2008 Archives

April 4, 2008

Speaking at JavaOne! TS-5098

Good news everyone!

My submission for a Technical Session at JavaOne has been upgraded from an alternate to an accepted session! TS-5098 - Building Rich Applications with Groovy's SwingBuilder. This will be given with Andres Alamiray. This is basically an intro to using Groovy to build Swing applications. No word on when the session will be however.

This is in addition to my BOF session on Wednsday Night with James Williams: BOF-5110 - Extending Groovy’s Swing User Interface in Builder to Build Richer Applications, which will go over how to add your custom widgets or leverage commercial libraries in the SwingBuilder.

April 9, 2008

SwingBuilder: Tight Groovy and Java Integration

Gregg Bolinger recently wrote a blog post illustratiing how Groovy's SwingBuilder can have two way integration with Java code. However, Gregg uses the javax.script APIs to integrate with groovy and Java. But the integration between the two can be made even tighter. How? Remember: every groovy script and class is also a Java Object. The GUI layout could be compiled in an entierly separate script, compiled, instantiated at runtime, and fed into the SwingBuilder. Consider these files...

//Panel.groovy
panel(id:'loginPanel') {
  tableLayout {
    tr {
      td { label(text:'Username') }
      td { textField(id:'usernameTextField', columns: 20) } 
    }
    tr {
      td { label(text:'Password') }
      td { passwordField(id: 'passwordTextField', columns: 20) }
    }
    tr {
      td { panel() }
      td { 
        button(text:'Login', actionPerformed: { 
          println user.username 
          println user.password 
        }) 
      }
    } 
  } 
}

bind(source:usernameTextField, sourceProperty:'text', 
     target:user, targetProperty:'username') 
bind(source:passwordTextField, sourceProperty:'text', 
     target:user, targetProperty:'password') 

With this model in a separate file (because I'm that kind of coder on occasion)

//User.groovy
class User { 
  String username 
  String password 
} 

Now before we go any further we will compile these scripts. Yes, with groovyc. If you are wondering if these are the complete sources the answer is yes they are. You are also correct in noticing that there is no import or use of SwingBuidler. <soapbox>This, my friends, is the power of a dynamic language. The MOP dispatches these calls, and when the script is actually invoked is when these symbols are resolved. When the SwingBuilder consumes the script it links itself into the script's metaclass to intercept all unresolved calls.</soapbox> Sorry, evangelical tangent there for a moment. Let's get back on task. How does the Java code look?

//JavaSwingBuilderDemo.java
import javax.swing.JPanel;
import javax.swing.JDialog;
import groovy.swing.SwingBuilder;

public class JavaSwingBuilderDemo {

  public static void main(String[] args) {
    SwingBuilder swing = new SwingBuilder();
    
    // load all externally referenced variables
    User user = new User();
    swing.setVariable("user", user);
    
    swing.build(new Panel());
    
    // unload the desired components
    JPanel result = (JPanel)swing.getVariable("loginPanel");

    JDialog dialog = new JDialog();
    dialog.getContentPane().add(result);
    dialog.pack();
    dialog.show();
  }

}

To invoke the script you do it much as you would in groovy, just with a lot more typeing. Both the keyboarding a casting kind. The main call is SwingBuilder.build(Script). This calls the script as though it was being evaluated in one of the builder's content nodes. Of course, before you call the script you need to load in any external variables, in this case a user object that contains the username and password. Then after the call you need to unload the variables you want to use. In Groovy I could just do swing.loginPanel but in Java no implicit meanings are allowed, so that means more typing.

An interesting side note is that this is similar to something we are looking at doing inside my own company: using SwingBuilder to build and wire up the GUI while keeping the core of the application in Java and keeping those who don't have the time to learn Groovy or want to deal with it from having to do so. And that is what I find great about Groovy: you can use it where it makes sense and adds value, and where you transition it's relatively seamless (unless of course you are using Seam ;) )

April 29, 2008

@Bindable - Observable Properties for Groovy

Groovy 1.6 is about to hit it's first beta here pretty soon, so I thought I'de spend some time writing about an implementation of the second big feature. in 1.6. Call site caching is the first big feature, and that is really just a technical term for 'faster.' The second big feature is AST Transformations. Right now it just triggers off of annotations, but there are already two implementations of it that are slated to ship, @Mixin (which I won't go into here) and @Bindable/@Vetoable. I'll go into the details of how you could write a transform later, but now I will focus on the most common task, simply using it.

@groovy.beans.Bindable is an annotation that can go either on a Groovy class property or a Groovy class itself. When the annotation is on a class you are telling the transform that all properties declared in the class should be treated as having @Bindable (whether or not they already have it). When a property has this annotation the AST Transformation will generate (if it doesn't exist) a java.beans.PropertyChangeSupport object, appropriate listener addition methods, and then a setter that uses the property change support. The end result is a bound JavaBeans property, with a whole lot less boilerplate code. What was once this:

import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;

class MyBean {
  private String prop;

  PropertyChangeSupport pcs = new PropertyChangeSupport(this);

  public void addPropertyChangeListener(PropertyChangeListener l) {
    pcs.add(l);
  }

  public void removePropertyChangeListener(PropertyChangeListener l) {
    pcs.remove(l);
  }

  public String getProp() {
    return prop;
  }

  public void setProp(String prop) {
    pcs.firePropertyChanged("prop", this.prop, this.prop=prop);
  }
}

now looks a lot more concise and to the point:

import groovy.beans.Bindable

class MyBean {
  @Bindable String prop
}

This goes hand in hand with the bind() node in swingbuilder, making a model update a text field automatically when it changes is now a simple as textField(text:bind(source:myBeanInstance, sourceProperty:'prop')). This is a very sublte thing to grok, but it really goes a long way in cutting down the amount of lines it takes to link the model and the view togeather in a client application.

The same premise goes for @Vetoable, you know, for all those constrained JavaBeans properties you write. You know, just in case. I have seen some code in the wild that uses VetoableChangeListeners, but not indexed JavaBean properties. It is useful for validation, when architected properly.

April 30, 2008

Consumer JRE - I think they may have pulled it off.

On my system I use two browsers: Mozilla and IE. Our customers use IE (its functionally as if they have a law to do so) so whenever I need to tweak web stuff (it happens on occasion) I fire up IE to test it. There is also another reason as well, I don't install flash on my Mozilla instance. Flash ads are extremely annoying, and almost never are relevant to me (lower my rates? Below 4.375%?). So I am in the habit of seeing the bevel box and thinking "is it worth firing up IE to watch this YouTube video." This makes getting RickRoled that much more annoying.

So I am going to this Baseball Salary Comparison (via NYT/Freakonomics) in Mozilla and I am scratching my head. Is AJAX that powerful now? Did flash sneak into my plugins? Is Silverlight in XP SP3? So I view the source and... oh my... it's referencing a class file. Where was the browser halting startup? The grey box? The orange java logo? I look down to my system tray and, yep, there's the java logo. I do have 6u10Beta installed, so all of the consumer oriented goodness is wired in by default, and it worked.

Oh my, I started a Java applet and didn't know it.

About time.

About April 2008

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

December 2007 is the previous archive.

May 2008 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