GWT UiBinder Hello World Tutorial

January 19th, 2010

I’ve been working on a new project the past couple of weeks that (fortunately) requires Google Web Toolkit (GWT) and I wanted to use the new UiBinder that was released with GWT 2.0 in early December for a number of reasons (clean separation of UI and code, easier collaboration with designers, easier testing, etc ). However, I was having a hard time getting my head wrapped around it given that the GWT site has very little documentation and only a few examples. I’ve combed through the message boards, the docs and the sample Mail application that comes with the SDK and after finally groking the new functionality, I put together a little Hello World app, the kind that would have helped me out originally.

So I’m making some assumptions that you already have the GWT SDK and Eclipse Plugin installed and are familiar with both of them. If you are not, take a look at the GWT site for more info.

To get started, create a new Web Application Project called “HelloUiBinder” in the package of your choice but do not check “Use Google App Engine”.


Now create a new UiBinder template and owner class (File -> New -> UiBinder). Choose the client package for the project and then name it MyBinderWidget. Leave all of the other defaults. When you click Finish the plugin will create a new UiBinder template and owner class.


Open the MyBinderWidget.ui.xml template and add the following code. With GWT you can define your styles either in your template where you need them or externally. I’ve added a small style inline that adds some pizzaz to the label. Notice the field name myPanelContent in the template. You can programmatically read and write to this field from the template’s owner class. So when the owner class runs, it construct a new VerticalPanel, does something with it (probably add some type of content) and then fill this field with it.

Attributes for the elements (the text attribute in the Label element for example) correspond to a setter method for the widget. Unfortunately there is no code completion to get a list of these attributes in Eclipse when you hit the space bar so you either have to know the setters or refer to the JavaDocs each time. A painful process.

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
     xmlns:g="urn:import:com.google.gwt.user.client.ui">
     <ui:style>
          .bolder { font-weight:bold; }
     </ui:style>
     <g:HTMLPanel>
          <g:Label styleName="{style.bolder}" text="This is my label in bold!"/>
          <g:VerticalPanel ui:field="myPanelContent" spacing="5"/>
     </g:HTMLPanel>
</ui:UiBinder>

For the owner class, MyBinderWidget.java, add the following code. In this class, a field with the same name, myPanelContent, is marked with the @UiField annotation. When uiBinder.createAndBindUi(this) is run, the content is created for the VerticalPanel and the template field is filled with the new instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.jeffdouglas.client;
 
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
 
public class MyBinderWidget extends Composite {
 
     private static MyBinderWidgetUiBinder uiBinder = GWT
               .create(MyBinderWidgetUiBinder.class);
 
     interface MyBinderWidgetUiBinder extends UiBinder<Widget, MyBinderWidget> { }
 
     @UiField VerticalPanel myPanelContent;
 
     public MyBinderWidget() {
          initWidget(uiBinder.createAndBindUi(this));
 
          HTML html1 = new HTML();
          html1.setHTML("<a href='http://www.google.com'>Click me!</a>");
          myPanelContent.add(html1);
          HTML html2 = new HTML();
          html2.setHTML("This is my sample <b>content</b>!");
          myPanelContent.add(html2);
 
     }
 
}

Now change the entry point class to look like the following.

1
2
3
4
5
6
7
8
9
10
11
12
package com.jeffdouglas.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
 
public class HelloUiBinder implements EntryPoint {
 
     public void onModuleLoad() {
          MyBinderWidget w = new MyBinderWidget();
          RootPanel.get().add(w);
     }
}

Now open HelloUiBinder.html and remove all of the HTML content between the </noscript> and and </body> save it. Once you run the application, copy the development URL and run paste it into your favorite supported browser, you should see the following.


Now suppose you wanted to nest a widget inside your MyBinderWidget that did something when a button was clicked. We’ll create a small series of checkboxes that allows the user to select their favorite colors and display them when the button is clicked. Create a new UiBinder called FavoriteColorWidget in the client package. Add the following code to the FavoriteColorWidget.ui.xml template.

1
2
3
4
5
6
7
8
9
10
11
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'>
    <g:VerticalPanel>
      <g:Label ui:field="greeting"/>
      <g:Label>Choose your favorite color(s):</g:Label>
      <g:CheckBox ui:field="red" formValue="red">Red</g:CheckBox>
      <g:CheckBox ui:field="white" formValue="white">White</g:CheckBox>
      <g:CheckBox ui:field="blue" formValue="blue">Blue</g:CheckBox>
      <g:Button ui:field="button">Submit</g:Button>
    </g:VerticalPanel>
</ui:UiBinder>

Now add the click handler in the FavoriteColorWidget.java owner class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.jeffdouglas.client;
 
import java.util.ArrayList;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
 
public class FavoriteColorWidget extends Composite {
 
     private static FavoriteColorWidgetUiBinder uiBinder = GWT
               .create(FavoriteColorWidgetUiBinder.class);
 
     interface FavoriteColorWidgetUiBinder extends
               UiBinder<Widget, FavoriteColorWidget> {
     }
 
     @UiField Label greeting;
     @UiField CheckBox red;
     @UiField CheckBox white;
     @UiField CheckBox blue;
     @UiField Button button;
 
     public FavoriteColorWidget() {
          initWidget(uiBinder.createAndBindUi(this));
 
          // add a greeting
          greeting.setText("Hello Jeff!!");
 
          final ArrayList<CheckBox> checkboxes = new ArrayList<CheckBox>();
          checkboxes.add(red);
          checkboxes.add(white);
          checkboxes.add(blue);
 
         // add a button handler to show the color when clicked
          button.addClickHandler(new ClickHandler() {
               public void onClick(ClickEvent event) {
                    String t = "";
                    for(CheckBox box : checkboxes) {
                         // if the box was checked
                         if (box.getValue()) {
                              t += box.getFormValue() + ", ";
                         }
                    }
                    Window.alert("Your favorite color/colors are: "+ t);
               }
          });
 
     }
 
}

The last thing we’ll need to do is add our new widget to the MyBinderWidget template. Open MyBinderWidget.ui.xml and add the custom namespace reference and the FavoriteColorWidget.

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">;
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
     xmlns:g="urn:import:com.google.gwt.user.client.ui"
     xmlns:c="urn:import:com.jeffdouglas.client">
     <ui:style>
          .bolder { font-weight:bold; }
     </ui:style>
     <g:HTMLPanel>
          <g:Label styleName="{style.bolder}" text="This is my label in bold!"/>
          <g:VerticalPanel ui:field="myPanelContent" spacing="5"/>
          <c:FavoriteColorWidget/>
     </g:HTMLPanel>
</ui:UiBinder>

Now when you run the application it should look like the following.


  • Share/Bookmark

Related posts:

  1. GWT UiBinder – Passing Parameters to Widgets
  2. UiBinder with SuggestBox & MultiWordSuggestOracle
  3. GWT UiBinder – Passing Objects to Widgets
  4. Tutorial: Salesforce.com with Flex and BlazeDS
  5. Google Releases Google Web Toolkit 2.0

Categories: GWT, Google, Google App Engine

Leave a comment

Comments Feed10 Comments

  1. Iqbal

    Hi Jeff,

    Nice entry. Your post help me figure out how to get UiBuilder work. I’ve also written a mini how to based on this article to show how to get UiBuilder work with non-GWT widgets using only HTML based UI.

    Thanks.

    Iqbal

  2. Iqbal

    ooopppsss forgot to provide the url to my tutorial site….

    http://wp.me/PnkVx-L

  3. Mike

    Great job. I have been looking for an example that shows all the pieces for days. Thanks!

  4. jeffdonthemic

    Glad I could help out!!

  5. Ashish

    This was an extremely useful breakdown of a simple concept. Trust me gwt documentation made it look way complicated then what you’ve manged to to.
    Thanks a ton!

  6. jeffdonthemic

    No problem! I thought the exact same thing!

  7. Ashish

    I actually have a question regarding usage of uiBinder. Not sure if this is the right forum .. I’ll still ask…

    It seems like uiBinder is a mechanism to provide a data template for a widget / html .
    So whatever is the myname.ui.xml corresponding myname.java class is generated and the template can be used inside it.

    What if I have some custom widget and I need to have a template (provide name-value pairs not layout) for it, if i go the uiBinder way do I have to stick to the class name which would mean i cant really re-use my widgets.

    Currently I was using a simple mechanism whereby the template was defined as a div with attribute name-value pair and the custom widget can read/write using DOM functions..

    I hope I was able to explain the question properly..
    thanks

  8. antonio

    thak you very much!
    this is really a good tutorial!

    I don’t know why documentation is so poor…

    Now I’m trying to use a widget that requires argument, but also in this case documentation is very poor… :-(

    Someone can post an example?

    Thanks!
    ciao
    Antonio

  9. jeffdonthemic

    Antonio, I’ll try to post something for you today or tomorrow.

  10. GWT UiBinder – Passing Parameters to Widgets | Jeff Douglas – Technology, Coding and Bears… OH MY!

    [...] received a number of emails regarding my last post, GWT UiBinder Hello World Tutorial, specifically how to pass values into widgets using the new GWT 2.0 UiBinder. Here’s a small [...]

Leave a comment

Feed

http://blog.jeffdouglas.com / GWT UiBinder Hello World Tutorial