Introduction to GWT UI Binders & Templates

As I touched on in a recent post about HTML document flow, I strongly believe that making decent GWT applications depends on understanding the underlying HTML that you are creating. In other words, you can’t get away with making a web application without actually understanding HTML and CSS :) Using GWT is no exception to this rule.

One of the biggest improvements I’ve seen in GWT in this respect is the introduction of UiBinders, also known as “Declarative Layout”. UiBinders provide a way for you to declare the layout of your application and widgets using traditional HTML and CSS rather than programatically in java. This provides you with a much richer way to create your application.

Think of UiBinders as stateful templates. Unlike traditional templates that simply know how to render provided data into static HTML, UiBinder templates describe how a single Widget should be represented in the DOM and provides that widget with references to the created elements. This makes it easier for the widget to interact with the elements, such as setting up events or modifying content without having to make additional DOM lookups.

As an example, lets say you were creating a chat widget, similar to the chat windows found in Gmail or Google+. Since it’s quite tedious to make such a complex UI by hand in Java, you’d want to use a UiBinder template. In such a widget, you’d probably have a send button and some sort of panel that displays your chat log. In this case your widget could maintain references to those two elements in the DOM but leave their rendering and markup up to the template.

Example

Ready for something more concrete? Lets see how this might look in code:

public final class ChatWidget extends Composite {

  // The @UiField annotation tags elements that the widget should
  // maintain references too.
  @UiField Button sendButton;
  @UiField DivElement chatLog;

  @Inject
  ChatWidget() {
    initWidget(binder.createAndBindUi(this));
  }

  @UiHandler("sendButton")
  void handleSendClick(ClickEvent event) {
    // send message...
  }

  public void appendMessage(String message) {
    chatLog.setInnerText(chatLog.getInnerText() + message);
  }

  private static final Binder binder = GWT.create(Binder.class);
  interface Binder extends UiBinder<Widget, ChatWidget> {}
}

And a corresponding ui.xml binder:

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">

<ui:UiBinder
   xmlns:gwt="urn:import:com.google.gwt.user.client.ui"
   xmlns:ui="urn:ui:com.google.gwt.uibinder">

  <ui:style>
    .log {
      border: 1px solid black;
      background: #CCC;
    }
   
    .button {
      background: blue;
    }
  </ui:style>
 
  <gwt:HTMLPanel>
    Chat History:
    <div ui:field="chatLog" class="{style.log}"/>
    <gwt:Button ui:field="sendButton" styleName="{style.button}" />
  </gwt:HTMLPanel>

</ui:UiBinder>

 

Breaking the example down

Rendering the template

There is quite a bit going on here – so lets break it down a bit. The first step in making your widget template aware is declare a custom UiBinder class and instantiate it using GWT.create(). This basically creates a class that can render your template on demand.

private static final Binder binder = GWT.create(Binder.class);
interface Binder extends UiBinder<Widget, ChatWidget> {}

The next step is to actually use your template. You can see this in the widget’s constructor where it calls binder.createAndBindUi(this). This effectively tells the binder to render a new instance of the template and bind it to the current widget. It’s here the all the magic is done in terms of providing the widget to the created DOM elements.

Defining the Template

When you define a Binder class, you should create a corresponding WidgetName.ui.xml. This xml file will contain both your html and css.

Your template files commonly have two top level elements:

  • A ui:style tag that contains all of your css definitions for this template. You can reference these style names in this template file by using “{style.class-name}”
  • A root or top level widget for this template. In this example it’s the HTMLPanel. Note that you can only have one top level widget – everything else must go underneath

Tip: An HTMLPanel is a common choice for use as a top level widget, since it allows you to mix raw html and widgets within your template.

Setting up events and updating state

To make your widget aware of elements in your template, you use the special “ui:field” attribute. Any element that has a field attribute can be referred to directly in your java class by defining a @UiField annotated member variable of a corresponding type. You can then have your class change the state, listen to events, change styles, etc – and have your changes updated in the UI immediately.

// In ui.xml file:
<gwt:Button ui:field="myButton" />

// In java file:
@UiField Button myButton;

// Elsewhere in the java file:
myButton.setText("Huzzah!");
myButton.setEnabled(false);

Note that you can refer to both Widgets and underlying DOM elements in your template file. If you want to refer to a DOM element, you’ll need to use the gwt dom classes, such as DivElement or SpanElement

To listen to events, you can use GWT’s shorthand @UiHandler notation (warning: only works for widgets that expose that event). Simply annotate any method (name doesn’t matter) with @UiHandler(“fieldName”) and have it accept the relevant event as a parameter.

 @UiHandler("sendButton")
  void handleSendClick(ClickEvent event) {
    // do something...
  }

The downside with the UiHandler annotation is that it only works with event’s that the widget normally exposes (such as click events on buttons). It doesn’t support any of the regular DOM events, so the second you want to go outside the fairly limited API it doesn’t work.

The common way to listen to any of those DOM events is to use the “addDomHandler” method. Example:

sendButton.addDomHandler(
        new MouseOverHandler() {
          @Override
          public void onMouseOver(MouseOverEvent event) {
            // Do something.
          }
        },
        MouseOverEvent.getType());

 

Further Reading

This should get you started with creating some basic templates. However, I also recommend giving GWT’s UIBinder documentation a quick scan which that has lots of extra details.

Posted in Google Web Toolkit | Comments Off

GWT widgets and their underlying HTML elements

In GWT you often work on the Widget or Panel level when composing your UI’s. As I touched on in a recent post on document flow, each of these underlying widgets are built using a basic html element that affects the way they content is displayed on the screen.

Here’s a quick rundown on GWT widgets and what they map to in the HTML world:

Widget Underlying Element Display Type Notes
Anchor, Hyperlink a inline
Button, PushButton, ToggleButton button inline
FlowPanel div block A general stand-in for a div when it will only ever hold widgets. If you need to hold html too, consider the HTMLPanel.
HorizontalPanel table table Never use this widget.
HTMLPanel div or span (see notes) block or inline The HTMLPanel widget is a special widget that supports arbitrary html and widgets. It is normally used in in tandem with ui.xml templates. Out of the box, it is represented
as a div, but can be be implemented using any html element by using the “tag” attribute.
PopupPanel div absolutly positioned block Overlaid over existing document flow
SimplePanel div block A div with restrictions of only holding a single element.
SuggestBox input inline
TextArea textarea inline
TextBox input inline
VerticalPanel table table Never use this widget.
Posted in Google Web Toolkit | Tagged , | Comments Off

Revisiting HTML document flow in GWT

One of the more common mistakes I see in GWT development is to forget that behind all the widgets, and panels, and abstractions of GWT, your application is fundamentally still HTML, CSS, and Javascript.

On it’s own, GWT simplifies your javascript development and provides a framework to help with building your UI. It is not, however, a replacement for understanding HTML and basic CSS. I firmly believe that to make a decent GWT application, you need to have an understanding of how it all works together.

That said, here’s a brief re-cap of some of the fundamentals of HTML document flow that’s easy to look over when you’re working in GWT land:

Document Flow: Block, Inline, & Inline-Block

Every html element contributes to the flow of content on the page. Most of these elements are classified as either block level elements or inline elements, which affects how they fit into the flow of content. Elements may have their natural display mode changed via CSS by setting the display attribute.

Block Elements

Block elements span the entire width of their parent element and cause the next element to start on a new line. In effect, they stack on top of each other like blocks. Block level elements accept the full range of css margin and padding styling.

Examples include: <div>, <p>, <form>, <blockquote>, <h1>, <h2>, and <ul>.

Inline Elements

Inline elements, on the other hand, fit into the regular flow of text on the page and will automatically wrap when they reach the end of a line. Think of them as individual words or glyphs. Some special notes when dealing with inline elements:

- No width or height can be set
- While padding and margins can be set, only the horizontal values will affect content
- Never put a block level element inside of a inline level element

Examples include: <span>, <a>, <em>, <strong>, <input>, <button>, <image>

Inline Block – The Hybrid

Inline-block elements are a hybrid of block and inline block elements. They get the benefit of fitting into the flow of text like inline-elements, but they still support width, height, padding, and margin. Lets say you were to make a custom button in GWT with your own styling: you would probably end up using an inline-block display mode so you could get all your dimensions the way you want.

Inline-block is only recently cross-browser compatible – and you may run into a few quirks when working with IE6/7 (every other browser should work fine). My golden rule for working with it that tends to get rid of 99% of cross browser problems: only ever set display:inline-block on elements that are naturally inline elements.


Fitting them all together


 

Where do GWT widgets fit in?

Each GWT widget is implemented using an underlying native HTML element that will affect the document flow. When you use a widget, its important to realize what element you’re using behind the scenes, otherwise your your layout starts to become very haphazard. For reference, I’ve created a short table of some of the more common widgets.

Generally, most panel widgets are divs (blocks) and inputs, buttons, links, etc. map to their corresponding span elements as you would expect.

The exception to this rule is the HorizontalPanel and VerticalPanel. These widgets use table elements behind the scenes, and I strongly recommend you never use them for layout purposes.

 

Common Document Flow Mistakes in GWT

  • Don’t set width 100% of block level elements. Block level elements naturally expand to fill their parent element horizontally – making the width 100% redundant. Even worse – width 100% is additive with padding and margin which can cause your div to expand outside of its parent all together.(The only exception to this rule would be if you are trying to clear floats using the overflow:auto technique. Still be on the lookout for margin and padding issues though)
  • Don’t put a width, height, or vertical padding/margin on inline elements – they have no affect. If you need them – use inline-block elements. Another common technique to force vertical size is to apply a css line-height to the span.
  • Never put display:inline-block on div’s or natural block elements. You’ll run into problems with IE6 and IE7.
  • Never use tables for document layout purposes. This means that HorizontalPanel and VerticalPanel are strictly off limits.
  • Never put a block level element inside a inline or inline-block level element.
  • Clear your floats, otherwise you’ll run into problems with the content overlapping the document down stream. Two common techniques are to put a clearing block (<div style=”clear:both”/>) or using the overflow:auto technique.


Posted in Google Web Toolkit | Tagged , | Comments Off

Getting started with GWT

Google Web Toolkit (GWT) is a useful development framework intended for building complex javascript applications. It’s used fairly heavily in Google products, and if you’ve used different Google services in the past, it’s likely that at least a few were built using GWT.

One of the interesting things about GWT is that it allows you to build your web application in Java. This has its pluses and minus, but generally this means that you can you reap all the benefits of a language with a developed tool chain (ie Eclipse). This may not seem like much for a small project (and might even be overkill), but for complex projects it can be extremely useful. It makes it easier to build, maintain, refactor, and test your product – which can become tricky when working with a big js code base.

To bridge the world of Java and Javascript, GWT uses a compiler. Your Java application is compiled into minified and obfuscated javascript files. To handle cross browser compatibility, GWT generates multiple “permutations” of your compiled application: one version for each for each browser. When your application is loaded in a web browser, GWT is able to detect the user’s current browser and load the right one for you.

With me so far? Want to give GWT a whril? Heres a few steps to get you started with a development environment. For the most part, these are just streamlined instructions from GWT’s Getting Started documentation. I prefer working with Eclipse, so these steps will show you how to get setup with it.

1.) Download Eclipse
If you don’t have Eclipse installed yet, head on over to the Eclipse Download page. As of this writing I’m using Eclipse 3.7 for Java Developers.

2.) Download and Install the GWT SDK + Plugin within Eclipse
Once Eclipse is setup, your next step is to download and install the GWT SDK. You can do this entirely within Eclipse using their “Install new Software” dialog.

Click Help –> Install new Software

Next, enter the site that matches your version of Eclipse.

(Indigo) http://dl.google.com/eclipse/plugin/3.7
(Helios) http://dl.google.com/eclipse/plugin/3.6
(Galileo) http://dl.google.com/eclipse/plugin/3.5

Next, place checks next to “Google Plugin for Eclipse”, and the “Google Web Toolkit SDK” (You can download the others if you want – they can be useful if you intend to deploy your application to App Engine, but aren’t strictly needed)

Click Next and Finish the installation wizard. It will take a few minutes while Eclipse downloads the SDK and installs it. At the end, Eclipse will restart to finish the installation.

3.) Create an Empty GWT Project

Now that your environment is setup, it’s time to create a simply GWT application. In Eclipse, click on File –> New –> Web Application Project

In the new dialog uncheck “Use Google App Engine”, and check “Generate project sample code”.

With that, Eclipse should auto-generate a bare-bones GWT application for you. One thing to note is that it puts the sample code into 3 main packages:

client: All your gwt application code goes here. Everything here will be compiled to javascript.

server: This is server side code that may handle ajax requests from your application via gwt rpc. For example, if your application were to communicate with a backend to get data through a database, it would call a service you program here. This is pure java code and isn’t intended to be compiled into javascript. Keep in mind that you are not required to use gwt rpc or program a service here. You can just as easily have a server written in PHP and have your gwt application communicate via JSON (or not have any backend at all)

shared: This is intended for shared classes between the server and client. These classes will be available in your server side code AND will be compiled into javascript. This is where you would put classes and interfaces for objects that you are sending via gwt rpc.

4.) Run your application in Development Mode
When eclipse created your project, it should have setup a default run and debug configuration for you. To kick off your application, try run –> project_name

 

In a second or so, you should see “Development Mode” tab appear with a link that you can use to view your application in a browser. Go ahead and hit the link and you should see the application popup in your browser (you may be prompted to install a GWT development plugin first)

Protip: I recommend using Firefox here – the GWT plugin performs ~2x faster in Firefox than in Chrome due to the way the extension APIs are built for each.

 

Whats going on here? For development purposes GWT uses something special called “hosted mode“. Basically, during development GWT doesn’t bother fully compiling your java into javascript. Instead – it talks with your browser via a special plugin and creates the javascript on demand.

Why is this important? Basically it means you can change any of your java code in your client, save, hit refresh, and see the changes instantly in your browser. Just like when working with regular javascript and HTML.

In the early days of GWT you used to need to re-compile the application every time you wanted to see your changes. Theres no need to do that now – it just wastes precious time when your developing your application.

5.) Compile your Application
Ready for others to see your application? Since others won’t have hosted mode, you’ll need to actually compile everything into plain-ol’-javascript and HTML first. To do that:

Right Click on your project –> Google –> GWT Compile

Within the new dialog, simply click “Compile”

 

You’ll see GWT work while a while while it does it’s magic: obfuscating, minimizing, prunning dead code… (aren’t you glad you weren’t running this every time you wanted to see a change?)

When done, you’ll see it output your completed compiled project in your war/ folder. Want to runthe finished product? Just open the root .html file in any browser. When it’s time to deploy, simply upload your .html and project/ folder to your web server.

 

Next Steps?
Now that you have a bare-bones GWT development environment setup, you’re free to start building away!

Not sure how to start? Google has some decent documentation, though it can be sometimes be a bit daunting for a beginner.  If you want something easier – I’m planning on adding some more tutorials on programming in GWT here. Feel free to add a ping in the comment section if interested!

Posted in Uncategorized | Tagged , | Comments Off

Creating an opaque background for photoshop paintings

A Photoshop technique I was recently asked about was how to create a semi-transparent background for tracing. This involves creating a layer with a low opacity that you can then draw or paint over, usually with a pen tablet.

As an example, lets say that you’ve taken a photo of a sunset that you’d then like to use for a painting. Here’s how you’d set it up for your painting session:

First off, create a new Photoshop canvas (File –> New). If you plan on doing some painting, be sure to keep the resolution decently high so you have some room to work.

Now that you have your canvas ready, lets load the photo that you want to trace. Hit “File –> Open”

 

Now you’ll have two separate canvases open. You’ll want to copy / paste the photo into your first canvas. To do this, press:

Select all: Press Ctrl + A
Copy: Press Ctrl + C
Switch over to the original drawing canvas
Paste: Press Ctrl + V

Heres what it looks like after you’ve pasted in the image to your first canvas:

Now that the image is pasted into your canvas, you’ll need to resize the image to fill all the space. Hit “Edit –> Free Transform”

You’ll see small ‘pips’ or corners appear on each of the corners of the image you’ve pasted. You can click and drag them resize it to fill the entire space. Hold down the shift key while you do it and the image will keep the right proportions. You can also click and drag on the body of the image to keep it centered on the page. When you have the image where you want it, press enter to apply your transformation.

Heres what it looks like now that we have it all centered.

Now it’s time to create the layer that you’re going to draw on. On the layer panel (usually in the bottom right) click on the new layer button. Before being able to draw on it, you’ll need to select it by clicking on it.

You’ll also want to lower the opacity of the of the photo layer so you can still see your painting above it. Click on the photo layer then click and drag the opacity slider near the top of the layer panel.

You’re drawing canvas should now look like this:

You’ll notice that its a bit hard to see since there is no background color to your drawing. Lets finish up everything by creating a third layer thats just solid white.

Hit the “new layer” button to create a third layer. Drag it to the bottom of the layer stack. Now it’s time to fill in the background layer with a solid color. Click on the paint tool, then select a solid white color from the palette. You can then click on the canvas to fill it.

Heres how your layers should now look:

And how your final image should now look:

And done! Now enjoy your your painting!

Posted in Photoshop | Tagged , , | Comments Off