GWT Layout and Tables

I don’t know about you guys, but for me, modern web development also means, to not use Tables for the Layout, but just when you actually want to show … a Table! Like a Table in a Document or so.

Contrary to this google seems to think different. At least GWT 2.3 google uses a lot of tables internally, also on elements where you would expect it does not use tables, and the W3C would kill a kitten if someone else would say they do it that way.

The most brutal example: See the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void onLoad() {
    FlowPanel panel = new FlowPanel();
    main.add(panel);

    VerticalPanel entry1 = new VerticalPanel();
    VerticalPanel entry2 = new VerticalPanel();
    VerticalPanel entry3 = new VerticalPanel();

    panel.add(entry1);
    panel.add(entry2);
    panel.add(entry3);

    HorizontalPanel hEntry1 = new HorizontalPanel();

    Label l1 = new Label(); l1.setText("bla 1");
    Label l2 = new Label(); l2.setText("bla 2");
    Label l3 = new Label(); l3.setText("bla 3");

    entry3.add(l1);
    entry3.add(l2);
    entry3.add(l3);
    entry3.add(hEntry1);
}

this does not produce, as someone would expect, a nice layout with different floating divs…. No, that would be to common… Actually: What that code produces is:

1
2
3
4
5
6
7
8
9
10
<div> <!-- ok, thats nice: the only table free layouter: the flow Panel -->
<table><tr><td> <!-- thats entry 1 --> </td></tr></table>
<table><tr><td> <!-- thats entry 2 --> </td></tr></table>
<table><tr><td> <!-- entry 3 starts -->
<table><tr>
<td>  <div class="gwtLabel">bla 1 </div> </td>
<td>  <div class="gwtLabel">bla 2 </div> </td>
<td>  <div class="gwtLabel">bla 3 </div> </td>
</tr></table>
</td></tr></table>

So, at least for me that is not what I call beautiful output of code. Actually, I would go as far as saying that is kind of unacceptable. Ok, there is a IE6, but really, we should damn that bloody browser, ignore him, and see him finally dying.

So, beside this example, actually most of the widgets in GWT make Tables. At least the following do that in 2.3:

  • VerticalPanel
  • HorizontalPanel
  • ListBox (no, it does not make an standard html options element)
  • CellList (sometimes a table might be ok here but…Smilie: ;)
  • Tree
  • CellTree
  • DatePicker (yes, the whole picker widget is designed with tables)

Ny opinion is that it makes sense in the following classes

  • FlexTable (should be a Table)
  • Cell* Calles sometimes are ok to be a Table
  • DataGrid

Of course, since this is that unacceptable, there are workarounds. One is to wait, until google reaches the post 90s area in Web Design, and doesn’t use Tables for Layout anymore. For the more impatient ones like me, you have to write your own Layouter. Since for most Layouts a vertical and Horizontal layouter + CSS Rules for their width and height will do, I guess having them making a non table tag version is most of the time sufficient.

The solution I will present is actually not my intellectual idea, but actually stolen from various sites. It is to use the FlowPanel, which already generates divs, and override the addWidget in a way it’s inner Elements get properly layouted.

This solution works quite well. There are only two gotchas: You would like to use display-inline for a vertical layout, but display-inline is not supported by IE up to 9. The second problem is, that these Layouter are still not the ones google uses, and so there own more complex ones still rely on tables. So if you want to do more complex layouts by yourself you either must compose them by your own, and also maintain it then by your own, or give in and use tables…..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public abstract class CustomFlowPanel extends FlowPanel {
    protected abstract String getFlowStyle();
    @Override
    public void add(Widget w) {
        w.getElement().getStyle().setProperty("display", getFlowStyle());
        super.add(w);
    }
}

public class HorizontalFlowPanel extends CustomFlowPanel {
    @Override
    protected String getFlowStyle() {
        return "inline"; // display-inline would be cooler
    }
}

public class VerticalFlowPanel extends CustomFlowPanel {
    @Override
    protected String getFlowStyle() {
        return "block";
    }
}

several people created solutions like that like f.e.:
http://showsort.darkhelm.org/doc/org/darkhelm/showsort/client/display/panels/VerticalFlowPanel.html
http://www.jarvana.com/jarvana/view/org/kuali/student/common/ks-common-ui/1.2-M1/ks-common-ui-1.2-M1-javadoc.jar!/org/kuali/student/common/ui/client/widgets/layout/VerticalFlowPanel.html
http://blog.sudhirj.com/2009/05/vertical-and-horizontal-flow-panels-in.html

Hope that discussion helped Smilie: ;)
Cheers, Joerg

Category(s): Uncategorized, web dev

5 Responses to GWT Layout and Tables

  1. The SEO guru says: Change your permalink structure (http://blog.jsimon.at/wp-admin/options-permalink.php) to include the title of the post in the URL.

    Besides that: Great post! Will definitely look it up again, if I ever need to use GWT …

  2. I say thanks to the CEO Guru. I have followed your advice, for it will help!

  3. Wisdom of the day: “though shall not change that setting, without enabling mod_rewrite”

  4. I am absolutely your opinion … I always used just the FlowPanels right because of the fact that they will be rendered as divs.
    However Google is not alone. Most of the famous webdev toolkits render tables .. a never ending story … but at last there are some people who work around it, thx! Smilie: :)
    keep the good work Smilie: ;)

  5. Thanks, it is a workaround, so it has it gotchas, but it is some help.

    Actually, if you use GWT 2.3 and obove, if more and more found out, that at least the new layouters like the DockLayoutPanel actually uses divs. My newest workaround is a design decision: Chaining the Widgets with UiBinder together, and make most of the markup by hand. I am writing an article for that. Then also using the Custom Vertical and Horizontal Flow Panels makes sense, and is not so much of an issue

Leave a Reply