This document provides code examples, notes, and screen-shots recorded while experimenting with FlexTable, a UI component from the Google Web toolkit (GWT). FlexTable is a flexible table that creates cells on demand. It can be jagged (that is, each row can contain a different number of cells) and individual cells can be set to span multiple rows or columns.
| package | com.google.gwt.user.client.ui.FlexTable |
| extends | HTMLTable |
Initial Setup
Since I know that my UI may be a complex assembly in the future, I like to create helper methods where each component of the assembly can be created. I then call those helper methods from
onModuleLoad() which is defined in the entry point class. Following is a minimal setup required to get a FlexTable rendering on the screen. It is from this basic starting point that we will build as we explore, learn, and have fun with FlexTable. We will be working with three files:
- App.java - the entry point class
- App.html - the application web page
- App.css - the cascading style sheet
App.java (initial setup)
Notice that I coded the createMasthead() method to return HTMLTable instead of FlexTable. Since the FlexTable extends HTMLTable, this creates more flexible code. In the future, I may decide that I do not like having FlexTable be the containing component for the masthead. I can change the method to return an HTMLTable or anything that extends it.
App.html (initial setup)
App.css (initial setup)
Rendered masthead (initial)
In FireFox, the result is as expected, but in IE, the 1px red border defined by the CSS class is not visible. It is no surprise that IE provides unexpected results.
FireFox

IE

Cell Alignment
The goal for my exploration seems simple enough. I want to create a simple masthead for a site or portal with three columns. I'm not sure that FlexTable is even the right component for the job, but that is partly what this exercise is intended to find out. A typical site masthead will have a logo on the left, a welcome message or some other minor element in the center, and then utility navigation and possibly even a search control at right.
My first task is to figure out how to align the content in cell 3 to the right so that eventually the utility navigation and search control in that cell will align nicely with everything on the right of the page. At this point, however, I cannot be sure that the table really is filling the page 100% in width and I cannot see the cells. If we right-click and view source in the GWT Browser, IE, or FireFox, we will not see any useful HTML because it is generated on the fly by JavaScript. This is where the FireBug plugin for FireFox comes in handy - it can show you the HTML that is created by JavaScript in the DOM as if it were HTML in the page source. How I ever lived without FireBug is beyond me! Here's how:
- Click the Compile/Browse button in the GWT Browser; this will compile the application and launch it in IE or your default browser.
- If it launches in IE instead of FireFox, just copy the URL from IE and paste it into FireFox.
- Activate FireBug by clicking the little green check at the very bottom-right of the FireFox window. If it is not there, select Tools/FireBug and make sure it is not disabled.
- Click the inspect button on top of the FireBug console and then hover over the masthead in the page. The DOM source code for the masthead will be shown in HTML as shown below:
Now I know I have a way to inspect the DOM that GWT creates, even though it doesn't really produce true HTML.
Anyway - back to cell alignment.
FlexTable has a special CellFormater called FlexCellFormatter which provides the following methods:
| getColSpan(int, int) | Gets the column span for the given cell. |
| getRowSpan(int, int) | Gets the row span for the given cell. |
| setColSpan(int, int, int) | Sets the column span for the given cell. |
| setRowSpan(int, int, int) | Sets the row span for the given cell. |
The FlexTable.FlexCellFormatter also extends HTMLTable.CellFormatter, so it inherits the following methods additionally. Since, I want to align the cell both right and top, I have chosen a method that looks like it handles both (marked with thumbs-up below):
| addStyleName(int, int, String) | Adds a style to the specified cell. |
| ensureElement(int, int) | Gets the element associated with a cell. |
| getAttr(int, int, String) | Convenience methods to get an attribute on a cell. |
| getElement(int, int) | Gets the TD element representing the specified cell. |
| getStyleName(int, int) | Gets the style of a specified cell. |
| getStylePrimaryName(int, int) | Gets the primary style of a specified cell. |
| isVisible(int, int) | Determines whether or not this cell is visible. |
| removeStyleName(int, int, String) | Removes a style from the specified cell. |
| Sets the horizontal and vertical alignment of the specified cell's contents. | |
| setAttr(int, int, String, String) | Convenience methods to set an attribute on a cell. |
| setHeight(int, int, String) | Sets the height of the specified cell. |
| setHorizontalAlignment(int, int, HasHorizontalAlignment.HorizontalAlignmentConstant) | Sets the horizontal alignment of the specified cell. |
| setStyleName(int, int, String) | Sets the style name associated with the specified cell. |
| setStylePrimaryName(int, int, String) | Sets the primary style name associated with the specified cell. |
| setVerticalAlignment(int, int, HasVerticalAlignment.VerticalAlignmentConstant) | Sets the vertical alignment of the specified cell. |
| setVisible(int, int, boolean) | Sets whether this cell is visible via the display style property. |
| setWidth(int, int, String) | Sets the width of the specified cell. |
| setWordWrap(int, int, boolean) | Sets whether the specified cell will allow word wrapping of its contents. |
I changed the code by adding the method as shown below:
Column 3 right aligned

Inspect in FireBug (proves it)
Adding Widgets
It is clear that I'm not going to have any more fun with FlexTable unless I try to put something in it. So, I will start with utility navigation. I have created another helper method in App.java as follows:
Then, I modify the createMasthead() method to call creatUtilityNav() instead of using plain text in the cell:
Rendered output in GWT browser:

DOM inspected in FireBug:
As you can see from the shots above, the utility navigation is vertically stacked. That is easily changed with a new CSS style rule:
Which results in...

Since we chose a FlowPanel, we also get nice wrapping at smaller resolutions instead of horizontal scrolling:

Next, I want to add my search utility. I created a method called createUtilities() that calls the method to create the utility navigation and the search control. Here is the output:

I don't want a Submit or Go button. That's just visual noise. In my design, the enter key will always submit the search. Here's the entire code so far that creates what is shown above:
Final adjustments
Just a little bit of adjusting and I've got it set. Following is my final screenshot and the final code.

And the code that produces it...
If you found this content useful, please let us know...
2 Comments
comments.show.hideNov 26, 2009
Anonymous
Great guide, keep up the good work.
Apr 08, 2011
Anonymous
Very useful. Thank you.