Tags First GWT

by Zack Grossbart on May 31, 2009

The Google Web Toolkit (GWT) speaks to all the Java programmers left petrified by the thought of web programming. GWT has a siren’s call: forget about cross browser issues, don’t bother with JavaScript, stay away from HTML. In reality, GWT requires deft piloting to stay off the rocks.

In case you’ve never heard of it, GWT is an open source project from Google that compiles Java code into JavaScript. You write your Java code just like a desktop application and get JavaScript on the other end. Instead of onClick=myFunction() you write myObject.addClickListener(this);

Desktop programmers love this style of programming because… well… we hate web programming. JavaScript feels beneath us. It isn’t strongly typed, isn’t object oriented, and doesn’t even have a compiler. A friend of mine described JavaScript this way: “You get a bunch of type safety bugs from the 1980′s.”

Desktop programmers want to focus on the implementation and the data; GWT speaks to us. “Don’t use a table tag, just use a FlexTable. Don’t use a div tag, just use a FlowPanel. Don’t worry about HTML. Forget about CSS. We’ll handle it for you.” And therein lies the rub. It does abstract away some of the complexity, but you can’t use GWT without an understanding of HTML and CSS. Without that, the developers and the designers have big problems. It happened in my company.

We started using GWT last year. We combined a team of seasoned desktop programmers with a designer who knows web programming. The designer spent awhile creating a prototype in HTML, CSS, and JavaScript. When he was satisfied with the prototype he sent it to the programmers and they said, “We can’t do that in GWT.”

Prototyping in HTML and then adding the data binding is a time tested design pattern. Why doesn’t it work with GWT? GWT doesn’t let you control the tags. You get table tags when you want div and div tags when you want span. GWT gave away a more polished UI for easier coding, and that is one exchange your users will never be thankful for.

StudyBlue ran into the same problem and their response was emphatic: “Use GWT to build the house, not to paint it.” Write the tags first. Don’t start with your database design or a UML diagram. Start with the HTML. Designing a prototype in HTML and working from that is possible. We’ll use the WordPress login screen as an example.

WordPress Login In GWT

wp_login

I use WordPress almost every day. Their admin UI is clean, functional, and polished. It’s one of the few web applications that makes me forget it is a web application. Let’s take the WordPress 2.7.1 login panel and write it in GWT.

Start by understanding the page. Notice that it has rounded corners, nice spacing, and pleasing background colors. It has something else. The HTML and CSS are already written. This is really important since most desktop programmers don’t have the experience to write CSS.

Using GWT’s FlexTable for this would meant rewriting the HTML and therefore the CSS. GWT widgets generate their own HTML tags and they don’t match up with the existing CSS. The goal is to keep the tags and use GWT for data binding. In order to use the existing CSS we need to keep the original HTML. Let’s look at it.

<form method="post" action="wp-login.php"
id="loginform" name="loginform">
  <p>
    <label>Username<br/>
      <input type="text" class="input"
      id="user_login" name="log"/>
    </label>
  </p>
  <p>
    <label>Password<br/>
      <input type="password" class="input"
      id="user_pass" name="pwd"/>
    </label>
  </p>
    <p class="forgetmenot">
      <label>
        <input type="checkbox" value="forever"
        id="rememberme" name="rememberme"/>
        Remember Me
      </label>
    </p>
  <p class="submit">
    <input type="submit" value="Log In"
    id="wp-submit" name="wp-submit"/>
  </p>
</form>

This HTML doesn’t use any table or div tags. The designer used p tags and we don’t want to lose that. We’ll start by escaping the HTML into a Java string.

Escape the HTML

There is no way around it: escaping quotes is a pain in the butt. PHP has a nice syntax to include strings that haven’t been escaped, but Java doesn’t. GWT is working on a way around this which may be included in the 1.6 release. Until then we need to encode the HTML as a Java string which means we need to escape all the double quotes with backslashes. It looks like this:

String html =
"<form method=\"post\" action=\"wp-login.php\"" +
"id=\"loginform\" name=\"loginform\">" +
  "<p>" +
    "<label>Username<br/>" +
    "<input type=\"text\" class=\"input\"" +
    "id=\"user_login\" name=\"log\"/></label>" +
  "</p>" +
  "<p>" +
    "<label>Password<br/>" +
    "<input type=\"password\" class=\"input\"" +
    "id=\"user_pass\" name=\"pwd\"/></label>" +
  "</p>" +
  "<p class=\"forgetmenot\">" +
     "<label>" +
        "<input type=\"checkbox\" value=\"forever\"" +
        "id=\"rememberme\" name=\"rememberme\"/>" +
        "Remember Me" +
     "</label>" +
  "</p>" +
  "<p class=\"submit\">" +
    "<input type=\"submit\" value=\"Log In\"" +
    "id=\"wp-submit\" name=\"wp-submit\"/>" +
  "</p>" +
"</form>";

Is this really necessary?

Escaping and embedding your HTML into a Java file is not ideal and there is an alternative. GWT includes an HTML file which anchors the JavaScript GWT will use. Normally this page includes only a single script tag.

We could add the HTML for our form there, but that would mean losing modularity. As your application gets more complicated the utility of separating different functions will become clear. Breaking your HTML up into separate pieces also encourages you to keep your HTML simple and use GWT to focus on data binding. Techniques like CSS-based form layout are a good way to simplify your HTML.

Remove the Fields

The power of GWT is in its data binding. We have the HTML, but we want to use GWT to bind the data. So we take all the fields out of the HTML and we are left with this:

String html =
"<form method=\"post\" action=\"wp-login.php\" " +
"id=\"loginform\" name=\"loginform\">" +
  "<p>" +
    "<label>Username<br/>" +
  "</p>" +
  "<p>" +
    "<label>Password<br/>" +
  "</p>" +
  "<p class=\"forgetmenot\">" +
    "<label>Remember Me</label>" +
  "</p>" +
  "<p class=\"submit\">" +
  "</p>" +
"</form>";

Create Your HTMLPanel

The format is ugly, but this chunk of HTML is very manageable. We can make it a GWT widget using GWT’s HTMLPanel. Using the string of HTML we just defined to create an HTMLPanel is easy:

HTMLPanel myPanel = new HTMLPanel(html);

Add Element IDs

The HTMLPanel really is that simple. However, we have two more steps before we can add the fields back. Each of our container tags must have an ID. I’ll show you why in a moment. We also want to remove the form tag. GWT submits all forms using JavaScript so you don’t need the form tag. We replace the form tag with a div tag, add IDs, and we get this:

String html =
"<div id=\"loginform\" name=\"loginform\">" +
  "<p id=\"username\" >" +
    "<label>Username<br/>" +
  "</p>" +
  "<p id=\"password\">" +
    "<label>Password<br/>" +
  "</p>" +
  "<p id=\"forgetmenot\" class=\"forgetmenot\">" +
    "<label>Remember Me</label>" +
  "</p>" +
  "<p id=\"submit\" class=\"submit\">" +
  "</p>" +
"</div>";

Bind the Fields

Now we are ready to bind the fields. The field binding happens by using HTMLPanel to do some very simple DOM mnipulation. We also set an ID for the TextBox’s element and apply a class (GWT calls it a style name) from our CSS. It looks like this:

TextBox user = new TextBox();
user.addStyleName("input");
user.getElement().setId("user_login");
myPanel.add(user, "username");

The last line here is where the magic happens. The HTMLPanel will add the new TextBox as a child of the element with the id username. We’ll add the rest of the fields the same way:

TextBox password = new PasswordTextBox();
password.addStyleName("input");
password.getElement().setId("user_pass");
myPanel.add(password, "password");

CheckBox forgetMeNot = new CheckBox();
forgetMeNot.getElement().setId("rememberme");
myPanel.add(forgetMeNot, "forgetmenot");

Button submit = new Button("Log In");
submit.getElement().setId("wp-submit");
myPanel.add(submit, "submit");

All of these fields are first class GWT widgets. We can submit them back to the server using AJAX calls, add listeners to fire events when the user changes them, or set their values programmatically. We have full support for any data binding we want.

Now that we have all the pieces, let’s put it together into a GWT EntryPoint. An EntryPoint is the main page for your application and it gets initialized when the onModuleLoad method is called. This method is where we need to put all the code we have.

Put It All Together

GWT is Java and in Java you must define a class. We’ll combine all of our HTML and data bound widgets into a class that implements EntryPoint. We can then add our HTMLPanel to the main page using RootPanel and add a ClickListener so we can see when the user presses the login button. The result is:

public class MyModule
implements EntryPoint, ClickListener {
  private static final String html =
    "<div id=\"loginform\" name=\"loginform\">" +
      "<p id=\"username\" >" +
        "<label>Username<br/>" +
      "</p>" +
      "<p id=\"password\">" +
        "<label>Password<br/>" +
      "</p>" +
      "<p id=\"forgetmenot\" class=\"forgetmenot\">" +
        "<label>Remember Me</label>" +
      "</p>" +
      "<p id=\"submit\" class=\"submit\">" +
      "</p>" +
    "</div>";

  public void onModuleLoad() {
    HTMLPanel myPanel = new HTMLPanel(html);

    // The username field
    TextBox user = new TextBox();
    user.addStyleName("input");
    user.getElement().setId("user_login");
    myPanel.add(user, "username");

    // The password field
    TextBox password = new PasswordTextBox();
    password.addStyleName("input");
    password.getElement().setId("user_pass");
    myPanel.add(password, "password");

    // The forget me not checkbox
    CheckBox forgetMeNot = new CheckBox();
    forgetMeNot.getElement().setId("rememberme");
    myPanel.add(forgetMeNot, "forgetmenot");

    // The log in button
    Button submit = new Button("Log In");
    submit.getElement().setId("wp-submit");
    myPanel.add(submit, "submit");
    submit.addClickListener(this);

    /*
     * Add our panel to the page
     */
    RootPanel.get().add(myPanel);
  }

  public void onClick(Widget sender) {
    /*
     * Our button was clicked...
     */
  }
}

The results will be exactly the same as the existing WordPress login, but have full data binding support from GWT.

Tags First

This example is simple, but the technique is a powerful way to write GWT applications. Tags first. You already know what you want the HTML to look like, so make GWT generate it. This technique has some clear advantages over the standard GWT way of doing things.

  1. You get total control over the tags.
  2. You don’t have to change your CSS.
  3. The integration between designers and programmers is much easier.
  4. You can still use standard GWT widgets when you want to.

This approach also scales very well. Create whatever complex HTML you need and then add the data binding. Want to create CSS form layouts like LinkedIn? No problem. Need to dazzle your clients with websites that rival Jason Santa Maria? You can still use the fast coding of GWT!

The promise of GWT is a powerful one: stop writing JavaScript. Not: stop writing JavaScript if you don’t care how your application looks. No tool is worth it if it doesn’t do what you want.

{ 10 comments… read them below or add one }

kebernet May 31, 2009 at 4:31 pm

Why would you not just use UIBinder or Kiyaa?

Dobes Vandermeer May 31, 2009 at 4:37 pm

We built our product, Clarity Accounting, using GWT and I ran into the same issue. To get around this I created a templating language based on facelets (another java technology for rendering XHTML pages). Basically you write the HTML page and the mark it up with special tags and attributes to attach your UI to it. A GWT generator converts the template into Java code that is compiled and run to invoke your events and so on.

Learn more at the Kiyaa! GWT Toolkit project:

http://code.google.com/p/kiyaa/

Zack May 31, 2009 at 5:23 pm

Thank you both for commenting.

I stayed away from UI Binder and Kiyaa because I didn’t want to introduce a new templating mechanism or special tags. My goal was to keep the HTML as close to the real thing as possible. I have also had problems with templating engines in the past from a maintainability point of view. Breaking the page into smaller pieces makes everything more reusable.I also wanted to avoid all logic in the HTML template.

All of that said, it depends on the application you’re writing. I used the techniques in this article to create a set of reusable widgets that are totally compatible with standard GWT. If you are creating a smaller application the simplicity of a templating mechanism would probably be the way to go.

Sakuraba June 1, 2009 at 1:55 am

If you would like to stay “html-centric”, why not use GwtQuery and use progressiv enhancements?

Zack Grossbart June 1, 2009 at 3:05 am

Sakuraba,

Thank you for commenting. I am a big fan of JQuery and often combine it with GWT applications. I haven’t used GWTQuery yet, mostly because it is so new. Looking at the documentation it looks like a good idea and yet another paradigm to work with.

I’m also a little skeptical of the GWTQuery claims of progressive enhancement. GWT applications are very reliant on JavaScript. Supporting browsers without it may be technically possible, but it feels like it goes against the philosophy of GWT.

Clay Lenhart June 1, 2009 at 5:57 am

Here is a blog entry on how to have complete control over the HTML tags in a GWT way: http://clay.lenharts.net/blog/2009/05/25/gwt-is-flexible-iphone-demo/

It uses two classes to accomplish this: GenericContainerTag and GenericTextTag.

shivaji July 10, 2009 at 1:10 am

i want to write an action for button like calculate
I have two text boxes which consists of values if i want to add both
it is xhtml+gwt

Zack Grossbart July 10, 2009 at 4:36 am

Hello Shivaji,

Thank you for your comment, but I’m not sure exactly what you mean. Can you give me a few more details or an example of what you are trying to do?

Thanks

David Pinn August 28, 2009 at 1:16 am

“You get table tags when you want div and div tags when you want span.”

Yes, that’s true; but what about simpler widgets? I notice that you’re trusting TextBox, PasswordTextBox, Button, and CheckBox to produce the HTML you expect. So which widgets do we trust, and which do we not?

Zack Grossbart August 28, 2009 at 2:44 am

David,

Thanks for the comment. I’ve grown to like the GWT widget model. The design pattern works well, but I have a few issues with individual widgets. In general I trust the form control widgets (Label being the exception) and I’m wary of the once used for layout. But that is just a rule of thumb. You need to look at each control and understand the pluses and minuses before you put it into a deployed application.

Leave a Comment

{ 1 trackback }