“Recreating the button” in GWT

On 3 Februari 2009 Google launched their new “custom buttons” in Gmail. The idea and creation process behind these buttons were described in the blog post Recreating the button at stopdesign.com, who were part of the process to develop these buttons. The buttons were designed for the following reason:

The buttons are designed to look very similar to basic HTML input buttons. But they can handle multiple interactions with one basic design. The buttons we’re using are imageless, and they’re created entirely using HTML and CSS, plus some JavaScript to manage the behavior. They’re also easily skinnable with a few lines of CSS, which was a key factor now that Gmail has themes.

Unfortunately, as with many UI widgets created by Google, these are not made publicly available via their GWT framework. Therefor I decided to recreate the button in GWT. I’ll describe some of the JavaScript and CSS issue I faced and how these were solved. If you want to go straight to the button and demo here are the relevant links: download, demo. Javadoc: Button and ButtonBar

Example of using the button in GWT

Design

The Button widget has been designed to look as close as possible to the look and feel of the Google button (read: pixel perfect). To make the usage of button easy it has same class interface as the PushButton widget from the GWT library, this makes it easy to replace existing buttons with the new Button widget. Additional there are several methods to easily change the color, size or text/button ratio. For the color I added a method that based on a hue and saturation value calculates all colors needed. This makes it easy to change the color of the button.

The button is constructed with nested <div> element’s. You can easily see this when you view the button with your favorite browser code inspector tool. Eventually I ended up with one <div> element less than in the Google button, which didn’t effect the layout as far as I my tests concluded.

JavaScript and CSS issues and fixes

After the basic reverse engineering I fixed the specific browser support issues, mainly related to the inline-block support. In the process the free browser testing service browsershots.org was of great help. But service only helps you with layout issues, not if the effects and actions work correctly. The Internet Explorer Application Compatibility VPC Image make it possible to test different versions of Internet Explorer. In the end I only didn’t fix IE 6 issues yet. Here are some details regarding the major issues:

DOCTYPE

It turned out that to display the button correctly in Internet Explorer 7 you need to set a DOCTYPE. It doesn’t matter which one, you just need one. So don’t forget to set one!

display:inline-block

What is interesting about the google button, is the use of the display property value inline-block. This property can be used to position block elements horizontally without having to float them. Because browser support has been very poor and using it is was not recommended. But newer browsers do support it and it won’t be long before you can safely use this property value.

Of the major browsers, support in Internet Explorer 7 can be achieved via the hasLayout trick, used in the button widget by setting display:inline and zoom:1 instead of display:inline-block. In the cobogw library there is a method CSS#setInlineBlock that will take care of different browser implementations.

Unselectable button text

If you check the Google button you will see that’s it’s not possible to select the text. Making text unselectable is normally not considered good practice, but in this case a normal button is also not selectable. But making something unselectable differs almost is all browsers. In the cobogw library there is a method CSS#setSelectable to take care of different browsers.

A small related issue is with Opera. In Opera when a user selects an element with a tab index it gets a different background color. For Opera 9.5 and later this can be removed via the CSS3 pseudo element ::selection. However, I didn’t find any way to set this via JavaScript, which means you need to set this in your own CSS file. This is documented in the Button JavaDoc.

Fire click event

A <button> element triggers a click event in case the user hits the space bar or the return key. However, a <div> element doesn’t have this behavior so programmatically a click event must triggered when the user hits one of those keys. It turns out this is also browser specific. IE does support the JavaScript method click() on the <div>. In the other browsers you need to do somewhat more. In short, you need to create a MouseEvents and call the dispatchEvent method on the <div> element with the a click event object.

For most other use cases it should not be needed to fire events that are normally only triggered by user interaction. If you find yourself doing such and are not creating ‘low’ level widgets like buttons you probably should reconsider your code. A method fireClickEvent that takes care of different browser implementations is available in the cobowg library to fire a mouse click event.

Posted in gwt, widget | Tagged , | 8 Comments

New name: cobogw.org, new widgets and GWT 1.5 support

Today I moved the gwt.bouwkamp.com project to a new name: cobogw.org. I guess, it’s completely unpronounceable ;-) , but I like abbreviations, the domain was free and the name isn’t used. That can be an issue nowadays. The new name is to better reflect the open source nature of the project (moving from a .com extension to a .org). The new project is hosted on google code, just as the old project was, http://code.google.com/p/cobogw/ (Or you can reach the project site via www.cobogw.org).

New release, GWT 1.5 support

I’ve released a packaged version of the cobogw project, which contains an easy to use jar file containing all widgets, source code and javadoc. With this release some new widgets are added and the jar file is also available as as GWT 1.5 compatible only version. You can find the zipped files at the download site. The new widgets/classes are:

  • Rating – A widget that allows users to set ratings (demo).
  • Span/TextNode – Widgets to add span an textnode tags to other widgets without overhead of additional div tags (demo).
  • CSS – A helper class to help with CSS properties.

On the project site you can also find examples and javadoc documentation for existing and new widgets.

Let me know what you think of the new name and new widgets.

Posted in gwt, widget | Tagged | 1 Comment

Fixing java.sql.Date/Time/Timestamp support for GWT

Probably anyone who uses the sql Date/Time or Timestamp classes and wants to use these in GWT needs wrap a custom implementation around these classes on the server side, because the java.sql classes are not supported by the current version of GWT (1.4.61). This is because for existing classes, like java.lang.String, GWT provides an emulated version. These are implemented for a large number of the java.lang objects among others, but not for these java.sql classes.

I had the same problem. I use Spring/Ibatis and maintained 2 data objects one on the server side used by Spring/Ibatis and on the client side which instead of the java.sql.Date used java.util.Date. The latter was used to communicate the data between the client and server.

When looking for a solution I found the problem was reported some time ago under issue 87 in the GWT issue tracker. But it’s marked with Priority-low. Furthermore, hibernate4gwt offers a solution, but I looked at the implementation of the emulated classes and missed some functionality. Therefore I wrote my own implementation to support java.sql.Date, java.sql.Time and java.sql.Timestamp to be fully compliant with the JRE classes (as far as is possible).

I prefer simplicity and packed the classes in a jar file, which you can simply place in your classpath to add support for the java.sql.Date, java.sql.Time and java.sql.Timestamp classes (presumingly you have already added User.gwt.xml to you module).

Download of the jar file, packed in a zip: cobogw.java.sql-1.0.zip

Because quality is important I created JUnit test cases to check the implementation. You can find the reports and test classes in my cobogw project repository.

Posted in gwt core | 1 Comment

Lessons learned

I’ve been working with GWT for more than a year and still think it changed the playing field. Joel Spolsky wrote an article about how GMail can be compared to what happened to Lotus 1-2-3 and that Google should watch out for some SDK that will change the landscape. I think that SDK can be GWT. Here are some lessons I’ve learned:

  • The GWT library takes away a lot of the burden of browser incompatibility related to JavaScript and therefor I don’t have to worry about browser JavaScript incompatibility. For new applications there are very few reasons to write your own JavaScript, unless you want to use a specific JavaScript or DOM element not accessible via GWT or want to integrate a some existing JavaScript code. Although when rewritten in GWT (i.e. Java) you can better debug the code.
  • What GWT does for JavaScript it doesn’t do for CSS or HTML. Which means that you still have to work around any CSS or HTML specific browser incompatibilities. CSS and HTML knowledge is very much required. I wrote a CSS helper class that contains all possible items and works around the ‘float’ issue. I’ve not released it officially but you can find it here (make sure you have all files and inherit the CSS.gwt.xml (or Users.gwt.xml)).
  • Programming GWT applications can be compared to writing classical GUI applications, like Java SWING applications.
  • Websites are created by web designers, who understand HTML and CSS, but probably are less familiar with programming. In GWT the whole design must be rewritten in GWT widgets, and none of the HTML created in the design can be reused. This makes the design/develop process more complicated.
  • In GWT there are two ways to set the style on HTML tags: programmatically and via CSS. The advantage of putting something in CSS is that it is easy to test your layout. I use the web developer extension in Firefox to dynamically alter the CSS style of an HTML page. When I’m satisfied with the style I hard code those properties that should not be changed, because when set differently they would break the layout. This makes reuse of the code more easy.
  • GWT does add a different dimension to HTML design. Because you develop in widgets and less in terms of HTML tags the notion of what is considered bad and good use of HTML blurs. For example, tables are considered bad it is better to use divs, the same for innerHTML. But all is hidden behind widgets. It becomes something you don’t care about. Although you have to because of the style differences between browsers on divs and tables. Some widgets are based on tables and could be rewritten in divs, but I found this very hard. I did a rewrite of the TabPanel widget with only divs, but to the implementations only worked if I didn’t use ‘quicks mode’.
  • With GWT you write in Java and debug your application in Java which makes it very easy to debug your code. Debugging is at Java language level, you are not debugging JavaScript. If you have custom JavaScript and you need to debug the JavaScript, you need to debug it using an external JavaScript debugger, which means you need to debug the generated code. I have not needed this, since I didn’t need any custom JavaScript, except for a few lines to set a very specific attribute not accessible via GWT.
  • GWT does lock you in. This means once you’ve writing your application in GWT ‘Java’ you can’t easily move it to some other library. The lock in is comparable with when you write your application in a specific programming language. For example if you would write you application in C# it’s not easy to move to some other language or library. The lock in is not necessary a bad thing because GWT is based on open source software and is open source itself, which is a good thing.
  • What is important to remember is that although you code Java for the client side it isn’t Java you’re writing. You are writing an application using Java syntax which is compiled to JavaScript. This is important to understand because it basically means you are writing in an unspecified language. This is partly true because in hosted mode your application runs as a Java program which means it really is Java. But eventually when you deploy your code it will be compiled to JavaScript. It also means that you can only use a very small set of the standard Java library, which is supplied with the GWT library.
  • The GWT compiler is currently limited to Java 1.4 syntax (Java 1.5 syntax is planned for GWT version 1.5). However, this doesn’t limit you to use JAVA 1.5 or 6, you simply can’t use specific Java 1.5 syntax in the client code. For the server side you can use whatever Java (syntax/library) you want.
Posted in gwt | 1 Comment