GWT Advocacy

Posted by Fred Sauer, Developer Advocate - Friday, January 16, 2009 at 9:57:00 AM

I'm a huge fan of GWT and have been since its public release in 2006. I have spent a fair amount of my spare time working with GWT by participating in the user forum and contributors forum, submitting patches to the issue tracker and maintaining open source libraries for GWT, including ones providing support for Drag and Drop (gwt-dnd), Logging (gwt-log) and sound (gwt-voices). GWT has gone through a number of exciting releases, with 1.5 easily being the most impressive release yet. You probably know that the team is fiercely working on the upcoming 1.6 release. Andrew posted a month ago about the new features slated for 1.6. As usual, I'm not sure if I'm more excited about what's in the upcoming release or all the possible things we can do next!

I'm pleased to announce that I have joined the Developer Relations team at Google as a Developer Advocate for GWT. Some of you may be wondering what a Developer Advocate does. The role has two parts. We are advocates for you, the developer, which is to make your voice heard within the product and engineering teams at Google. We also advocate broader use of Google Developer Products and APIs. Both roles work hand in hand. By listening to developer's needs I will be advocating to improve GWT as a product. A better product in turn helps increase adoption thereby growing the GWT community.

I look forward to spreading the word and to helping make GWT even better.

GWT Community Updates

Posted by Sumit Chandel, Developer Programs Engineer - Friday, December 19, 2008 at 10:00:00 AM

The GWT community is full of activity; so much so that it sometimes becomes difficult to keep track of! I thought it would be a good idea to try and gather some of this action in one place, so without further ado, here's what's going on in the GWT community!

Community announcements

Restlet 1.1.0 released: Using REST APIs with Servlets used to require wasted hours writing custom code. Fortunately, Restlet came along to take that pain away. Even more fortunately, Restlet integrates with GWT to make dealing with REST APIs a breeze. The team has recently announced their 1.1.0 release, might be worth a spin if you've exhausted yourself writing custom code and need some REST.

Hibernate4GWT (Gilead) 1.2 RC1: Hibernate is an extremely powerful ORM framework for the Java programming language. It has proven itself as an invaluable tool for those with tight data-to-domain mapping, and thanks to Hibernate4GWT, has become easily accessible to GWT application developers. Hibernate 1.2 RC1 (aka Gilead) is now available to download.

SmartGWT 1.0 released: SmartClient is a framework that allows you to not only utilize its widget library for your application UI, but also tie these widgets in with your server-side for data management. SmartGWT 1.0, combining both GWT and SmartClient, has been released thanks to the efforts of Sanjiv Jivan. Read more about it in Sanjiv's release announcement.

GWT Maven heaven: The gwt-maven project developed by Charlie Collins and fellow project members provides a way for developers using a Maven to easily integrate GWT into their build system. We also have Nicolas De loof who has been working on a GWT Maven plug-in in the Mojo project. We're happy to say that Charlie Collins and Nicolas De loof are now going to form GWT Maven heaven by integrating the functionality of both plugin together and hosting them on the Mojo project.

Put Your GWT App on Facebook in 10 minutes

Posted by Sumit Chandel, Developer Programs Engineer - Tuesday, December 16, 2008 at 1:33:00 PM

As you may know, social networks like Facebook, LinkedIn, and MySpace can be an excellent place to grow a new business. Most of the kaChing community first discovered us through friends using our Fantasy Stock Exchange Facebook app.

In this post, I'll help you get your GWT app running as a Facebook app. Believe it or not, it can be done in just two easy steps.

  1. Create the Facebook App.
    Follow the instructions on Facebook's Getting Started page to create and name your Facebook app. Accept the default settings for now.

  2. Point your Facebook App at your GWT App.
    Adjust these Facebook App settings:
    Callback URL Enter the URL of your GWT app's main HTML page. Tip: For a quick development cycle, run your server locally and use a localhost URL.
    Canvas Page URL Choose a path beneath apps.facebook.com for your Facebook app. Also select the Use iframe radio button.

And you're done! Visit the Canvas Page URL that you chose, and you'll see your GWT app running in Facebook. The rest of this post will suggest a couple of ways to integrate more fully, to better leverage the Facebook platform.


Getting rid of unwanted scroll bars

If your GWT app is too wide for the containing Facebook iframe and you can't stomach a horizontal scrollbar, then you need to make your app slimmer - at least when it's running inside Facebook. Facebook's width limit (currently 760px) is a hard limit.

If your GWT app is too tall, it'll be clipped and you'll see a vertical scrollbar along the right side. To fix this, you can specify a large fixed canvas height for your app using the CanvasUtil feature of Facebook's JavaScript Client Library. You can read the docs for more detail, but in practice it boils down to adding the following snippet to the body of your app's main HTML page:

<script type="text/javascript" 
  src="http://static.ak.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php">
</script>
<div id='FB_HiddenContainer' 
  style='display:none;position:absolute;left:-100px;top:-100px;width:0;height:0'>
</div>
<script type="text/javascript">
  window.onload = function(){
    FB_RequireFeatures(['CanvasUtil'], function(){
      FB.XdComm.Server.init('some/path/to/xd_receiver.html');
      FB.CanvasClient.setCanvasHeight('2000px');
    });
  };
</script>

You should customize the highlighted parts. Here's a description of what's going on in the snippet above:

  1. The first script tag loads FB_RequireFeatures, the entry point to the Facebook JS Client Library.
  2. The FB_RequireFeatures call loads the CanvasUtil feature (the FB.CanvasClient object).
  3. Before using FB.CanvasClient, we must set up a Cross Domain Communication Channel between your app's canvas window and the containing Facebook window. This means a) hosting Facebook's xd_receiver.html file somewhere on your server, b) telling the Facebook JS Client Library where to find it (hence the FB.XdComm.Server.init call), and c) adding an FB_HiddenContainer div to the body of your main HTML page to serve as the container for channel iframes.
If your app changes its height from time to time, you can ask the Facebook's JS library to check your canvas window's height at regular intervals and adjust the containing iframe's height to match. To do so, replace the FB.CanvasClient.setCanvasHeight call in the snippet above with:
FB.CanvasClient.setCanvasHeight('2000px',
function(){FB.CanvasClient.startTimerToSizeToContent()});

For more info on the CanvasUtil feature, including how to make the containing Facebook window scroll to a desired location, see this demo iframe app.


Accessing Facebook User Data

If a Facebook user is logged into Facebook when accessing your Facebook app, the app URL will include the user's Facebook ID in the query string as the fb_sig_user or fb_sig_canvas_user parameter, depending on whether the user has authorized your application. (See Authorizing Applications for more on the various request parameters.) You can use this Facebook ID, in conjunction with your app's ID and secret key, to request information about the user from Facebook using any of Facebook's various APIs. As a GWT app author, you are likely to be using a Java server, so consider using one of these Java Facebook clients. We use this open-source Facebook Java API.

For a high-level overview of Facebook's various APIs and their relative merits, I'd recommend a recent blog post by Facebook Platform engineer Charlie Cheever.


Get some Face time for your app

I hope this article helps you get your snazzy, snappy GWT apps to larger audiences. If you can afford the time investment, be sure to utilize social network integration points that can spur viral growth, such as invitations, profile boxes, and activity streams.

Spotlight On Developers Using Google Web Toolkit

Posted by Sumit Chandel, Developer Programs Engineer - Thursday, December 11, 2008 at 5:40:00 PM

One of the best resources for developers looking for tips on building applications or learning about a new technology is to hear from other developers who have already been through the experience and built world-class applications. That's why we're happy to share videos of a few developers who used the Google Web Toolkit to build rich, sophisticated Ajax applications that have wowed audiences, won prestigious awards and are pushing the boundaries of what we've come to expect from a web application.

Check them out in our new Who's Using GWT page. In these videos, the developers explain how they used GWT to build their apps, their opinions on GWT overall, and tips and learnings from working with GWT. These videos include the developers behind:

  • GoGrid: the cloud computing infrastructure service provider that won "Best of Show" at the Linux World 2008 Product Excellence Awards.

  • Lombardi Blueprint: a business process mapping and diagramming tool that was used as a case study at this year's Google I/O conference.

  • scenechronize: a film and television production management application, presented at the Sundance Film Festival and Festival de Cannes in 2008.

  • Whirled: a social virtual world website, where users can keep up with friends, discuss on boards, and play a number of wildly entertaining mini-games.

We'd love to hear from others in the community. If you would like to share your experience developing GWT applications with the rest of the community, let us know in the forum.

What's ahead for Google Web Toolkit

Posted by Andrew Bowers - Wednesday, December 10, 2008 at 2:53:00 PM

A lot of discussion occurs in the Google Web Toolkit contributors forum about development progress, feature requests, and the roadmap. We realize that many of you are very busy and would like to see a simple roadmap on the website, so we've updated "Making GWT Better" with our current plans.

As with any development work, its hard to exactly predict when things will land, so we've stayed away from specific dates and releases past the next one. You'll be happy to know that release 1.6 is well underway and on target for Q1 of 2009.

You can check for future updates in the Making GWT Better section of our website.

Release 1.6

Anticipated Time Frame - Q1 2009

  • New compiled file deployment structure
    • Easily compile into a war file structure, making it easy to deploy your compiled GWT application into standard servlet containers
  • Migration from Tomcat to Jetty hosted mode server
    • A more pluggable architecture for the hosted mode server will enable developers to use servlet containers other than Tomcat with the Hosted Mode browser
  • Uniform event handlers
    • Event handlers will be implemented in a uniform fashion across all widgets, with listeners deprecated
  • DatePicker, LazyPanel migrated in from incubator
    • New widgets from the incubator
  • String performance improvements
    • StringBuilder uses deferred binding to optimize string appends per-browser
  • Compiler performance improvements
    • 1.6 will introduce parallel permutation compilations and other performance tweaks for faster compiles

Post 1.6

The following are features that are on our roadmap for releases post 1.6, but are in various states of development. As we reach the end of the 1.6 cycle, we'll update the roadmap with which features we are targeting for the next release.

  • Developer Guided Code splitting
    • Developer guided code splitting is a mechanism that allows developers to specify asynchronous split points in their code where the code base can be split and downloaded in different chunks. This is currently an R&D project but looks promising.
  • Analysis of compiled code, aka Story of your compile (SOYC)
    • Aims to give developers concrete information about their compiled JavaScript, such as which Java classes are generating the most JavaScript code.
  • In-browser hosted mode, aka Out-of-process Hosted Mode (OOPHM)
    • In-browser hosted mode will allow GWT developers to debug their apps within a browser rather than GWT's hosted mode browser
  • UI Binder
    • The UI Binder will allow the creation of UI elements in a declarative fashion. Watch for UI Binder to land in the GWT incubator soon.
  • Client Bundle
    • Client Bundle implements the power of deferred binding used in Image Bundle in a generic fashion so that it can be used on many resources. These include TextResource, ImageResource, and CSSResource
  • RPC performance improvements
    • Ongoing work to improve the performance of RPC

Visualizations in your GWT application

Posted by Andrew Bowers - Tuesday, December 09, 2008 at 9:41:00 AM

For those of you interested in creating visualizations in your Google Web Toolkit applications, we're happy to announce the Google Visualization API Library for Google Web Toolkit (GWT). This adds another library of Java language bindings for JavaScript APIs provided by Google, collectively known as the suite of Google API Libraries for Google Web Toolkit.

We're also releasing a General Availability build of the Google Maps API Library for GWT. This build contains a few bug fixes that contributors have reported. Thank you for reporting those, and please continue to report them in the issue tracker.

You can read more about the new Visualization API in the announcement on the Google Code blog.

GWT: No need to shortchange your style

Posted by Sumit Chandel, Developer Programs Engineer - Monday, December 08, 2008 at 2:41:00 PM

We've been approached by many programmers and designers alike that question how we got such a custom look using GWT. Our response is simple, "Use GWT to build the house, not to paint it." When you build a new house, you don't have your building contractor pick out the furniture, choose the color palette, or stencil the walls. Similarly, you shouldn't use GWT to inject all the "style" into your website. Instead, you rough it out with GWT and push the design to CSS.

Whether you're building a small widget to embed in an existing site, or you're building an entire web-application from scratch (that's us :-) ), we recommend the following three tenants to ensure maximum design efficiency and flexibility:

  1. Know your design team

  2. Keep all visual elements in the CSS

  3. Deploy to a test environment

Know Your Design Team

Sticking with our home construction analogy, you might go about building a home by first having an architect envision a space, then having his apprentice detail the blueprints, before finally having a contractor build the house. Similarly, you should assemble a good design team before diving into the construction of your site with GWT. Chances are, if you are a strong Java programmer (i.e. "the GWT Programmer"), you are not as strong at CSS design and image slicing. You need to know what team members you have at your disposal, and what their strengths are. Once you're set with a Designer and a CSS Stylist (they may be the same person), we recommend you follow this general workflow:

  1. Create a Photoshop image of the widget/site. This file should assume that "anything is possible" and be the ideal look for your widget/site.

  2. Have the Web Designer slice the image into pieces that can be implemented using HTML Tables or DIVs. Even better if this stage can be accomplished with future flexibility in mind for mulitple uses, flexibility, etc...

  3. Layout the "blueprint" in complete HTML. Create exactly what the HTML code should look like after the respective GWT application code renders the widget/site.

  4. Begin building the layout using GWT. Remember to make mini-widgets out of every piece of reusable code.

Let's elaborate a bit on points 2, 3 and 4.

Part of knowing your team means understanding what your Web Designer's preferences are when it comes to using Tables or DIVs. GWT offers widgets that encompass both Tables (HorizontalPanel, FlexTable, etc.) and DIVs (FlowPanel, HTML, etc.). There are benefits and drawbacks to using each of them. For example, Tables might be good for vertical/horizontal centering or adding stability to a grid. They are poor for dynamic positioning, hover states, "rounded corners", etc. Whatever the case, both the GWT Programmer and the Web Designer should have an agreed understanding on which layouts (Tables or DIVs) are to be used and when it's appropriate to make exceptions. We prefer to do use DIVs, using FlowPanel much more often than HorizontalPanel or VerticalPanel.

Creating a "blueprint" is important for three reasons. First, it helps eliminate guess work from the GWT Programmer. An HTML "blueprint" can quickly be tested on all browsers to prove that the style renders to the structure as expected. Secondly, "blueprints" are an easy way to communicate between GWT Programmer and Web Designer without both parties having to be in the same room at the same time. Plus it makes it easy to assign blame when things don't look right :-). Finally, creating the "blueprint" will help you realize what looks in the original artwork are impossible to recreate on the site (hopefully none).

Note: Using the WebDeveloper plugin (or Firebug's Inspect) for Mozilla Firefox is a great way to inspect your final layout as a GWT Programmer, to make sure you match the "blueprint". More on this later.

Finally, when you start creating the layout in GWT, remember to break down each piece into a Composite class. Not every Composite you create will be reusable. Sometimes you have to make your widgets so specific that they can't be reused. That's OK, it's a common occurrence in UI programming. However, many widgets you can design to be reusable. One obvious example is "buttons" on your website.


Keep all visual elements in the CSS

We can't stress this point enough: PUSH YOUR STYLING TO A CASCADING STYLE SHEET (CSS). Just about everything you can do style wise can be done with CSS, so keep it that way.


BAD:

java
HTML randomText = new HTML("This is some random text in a DIV");
DOM.setElementProperty(randomText.getElement(), "color", "green");
DOM.setElementProperty(randomText.getElement(), "fontSize", "16px");

GOOD:

java
HTML randomText = new HTML("This is some random text in a DIV");
randomText.setStyleName("sb-TextWidgets-RandomText");
CSS
  .sb-TextWidgets-RandomText{
   color: green;
   font-size: 16px;
 }

So, what are we gaining by doing this?
  1. Changing something as simple as color or font-size requires only a CSS update as opposed to redeploying the whole GWT code.

  2. In the above case, we cut out one line of java code. When your application is 40,000+ lines, saving 1-4 lines for every single widget can greatly improve compile time and size.

  3. The Web Designer can make style changes without ever having to look at or run Hosted Mode. (*assuming you have a good test environment - see below)

So let's look at a more complex example, a navigation bar with "hover" and "selected" states. Below you'll notice we've created reusable code for our "hover" and "selected" state that can be used by any widget that we want to implement "hover" or "selected".

Hover Class:

public class Hover {

    private static MouseListenerAdapter mla;

    public static MouseListenerAdapter getHoverMla(){
        if(mla == null){
            mla = new MouseListenerAdapter(){
                    public void onMouseEnter(Widget hoverableWidget){
                       hoverableWidget.addStyleDependentName("hover");
                    }
                    public void onMouseLeave(Widget hoverableWidget){
                        hoverableWidget.removeStyleDependentName("hover");
                    }
                };
        }
        return mla;
    }
   
    .
    .
    .
}
Selected Class:
public class Selected {

    private List<HTML> itemList;

    private ClickListener cl;
   
    public Selected(){

        itemList = new ArrayList<HTML>();

        cl = new ClickListener(){
            public void onClick(Widget selectedItem) {
                for(HTML item : itemList){
                    if(item.equals(selectedItem)){
                        item.addStyleDependentName("selected");
                    }
                    else{
                        item.removeStyleDependentName("selected");
                    }
                }
            }
        };
       
    }
   
    public ClickListener getSelectedCL(){
        return cl;
    }
   
    public void addItem(HTML item){
        itemList.add(item);
        item.addClickListener(cl);
    }
   
    public void removeItem(HTML item){
        itemList.remove(item);
        item.removeClickListener(cl);
    }
   
}
Navigation Bar Class:
public class NavBar extends Composite{

    public static String BLOG_HOME="http://blog.studyblue.com/";
   
    private int ID=1;
    private Selected selector;

    public NavBar(){
        super();

        selector = new Selected();
       
        FlowPanel holder = new FlowPanel();
        holder.setStyleName("NavBar-Holder");    
       
        holder.add(link("Blog",""));
        holder.add(link("About Us","about"));
        holder.add(link("Jobs","about/jobs"));
      
        setWidget(holder);
    }

    private HTML link(String text, String location){
        HTML ret = new HTML(text);
        ret.setStyleName("nav-item-"+ID);
        ret.addStyleName("nav-item");

        selector.addItem(ret);
        ret.addMouseListener(Hover.getHoverMla());
        ret.addClickListener(new ClickListener(){
            public void onClick(Widget sender){
               ///Open popup with blog page location
            }
        });

        ID++;

        return ret;
    }

}
CSS code:
.nav-item {
    background-image: url(images/nav.png);   
    background-repeat: no-repeat;   
    background-position: 0 0;   
    display: block;   
    height: 0px;   
    padding: 30px 0 0 0;   
    overflow: hidden;
}

.nav-item-1 { background-position: 0 0;        width: 65px; }
.nav-item-2 { background-position: -65px 0;    width: 90px; }
.nav-item-3 { background-position: -155px 0;   width: 65px; }

.nav-item-1-hover { background-position: 0 -30px; }
.nav-item-2-hover { background-position: -65px -30px; }
.nav-item-3-hover { background-position: -155px -30px; }

.nav-item-1-selected { background-position: 0 -60px; }
.nav-item-2-selected { background-position: -65px -60px; }
.nav-item-3-selected { background-position: -155px -60px; }
Image File (nav.png)


So, let's break down what is going on here. The NavBar is a Composite which is holding a FlowPanel ("holder"). This FlowPanel is a DIV which is going to hold our 3 links: "blog", "about us", and "jobs". Each one of these links is an HTML widget (i.e. a DIV). Inside the method "link" we first are creating each HTML with the appropriate text, setting its style name with a unique integer, adding an additional style name. From there, we add the link to our "selector" as well as add a "hover" listener. Finally, we add a ClickListener which initiates an action (in this case taking the user to the blog).

Some things to note:

  • Note the difference between "setStyleName" and "addStyleName". HTML widgets come default with "gwt-HTML" as the SET style name. When you call setStyleName(), you replace "gwt-HTML" with whatever you choose. This new SET style name is what is used when the method "addStyleDependentName" is called. addStyleName() simply just adds an additional style, which is not used for "addStyleDependentName".

  • In our case, the "hover" and "selected" style names were added dynamically using addStyleDependentName(). So, we needed to make sure that the SET style name was the complete identity (i.e. "nav-item-1"). addStyleDependentName() takes care of adding the additional style names (i.e. "nav-item-1-hover" and/or "nav-item-1-selected").

  • The additional style name, "nav-item" is added permanently onto each link, but is not the SET style name. Thus, it is always present, despite the addition/subtraction of style dependent names.

  • The Web Designer and GWT Programmer both know that all widgets will have a style DEPENDENT name of "hover" and "selected" (if necessary), which means the GWT Programmer can recycle the Hover and Selected code, and the Web Developer can anticipate what style names will be present for "hover" and "selected"

  • *CSS Tip: Loading all of the states (off, selected and hover) into the one nav.png image, helps prevent flickering when the user hovers or selects the link.

Without our CSS, the result would simply look like this:

Blog About Us Jobs


However, by adding a few style names, we are able to achieve a look like this:


We also streamlined our development by standardizing the use of stand-alone buttons on the site. That way, the GWT Programmer can create a button widget that can be reused depending on the size and color button needed. The widget uses DEPENDENT style names to produce small, medium, or large buttons colored with green, white, blue, or red that are preset in the style sheet and work for flexible content lengths.


Deploy To A Test Environment

It is really important to have a test environment for your Web Designer to mess with. As a GWT Programmer, you can't expect that your Web Designer will be able to run Hosted Mode. Also, until the GWT guys implement Out-of-Process Hosted Mode (OOPHM), you will definitely want to take a look at your product in all the major browsers before deploying to production. We run a Tomcat instance on a powerful box over at Amazon Web Services. Using SVN and Ant, we update all our code to the test machine, compile it, create a WAR and deploy it using one command. The key here is that this process takes over 6 minutes every time we want to deploy new code. Six minutes may not seem like that long, but when your Web Developer is waiting 6 minutes every time you need to make a small change to the layout, it gets annoying. So we implemented two ideas to help ease the pain.

First, if you take one thing away from this post, don't style using the GWT DOM class. Set your style names and let the CSS do the work. If we had put all the styles in the GWT code, it would take us 6 minutes to change the color of some trivial text, only to find out that we liked it better the old way (another 6 minutes).

Second, pull out your CSS files and images directory to some location outside your WAR. The idea here is that the Web Designer can manipulate the CSS and imagery without ever getting inside your WAR. This way, when its time to deploy new code, you don't overwrite the Web Designer's changes by replacing the CSS file and/or images on accident. This also helps with remote collaboration. The Web Designer gives the GWT Programmer the "blueprints", the GWT Programmer builds the app and deploys it to the test server, the Web Designer is free to make changes to the CSS and images while checking compatibility across all the browsers. Theoretically, you'd never have to be in the same room (although we don't prefer it that way).

Now get out there and build an awesome GWT house!