Saturday, March 24, 2012

GWT in general and the CellTree widget

    I've been toying a bit with GWT and it's quite nice.

     In the past, I've used many frameworks to some extent, depending on what was needed : raw JSP with or without JSTL, Struts, VRaptor 1.x,  Cocoon, JSF, Velocity, Wicket, etc.
     I had more fun using Wicket than something like Struts 1.x for example...
     I never liked Struts but it seemed good enough compared to other frameworks at the time(Early ASP.NET versions were already more usable for medium size apps). If I were compelled to use something similar to Struts today, with the luxury of choice, I would likely select Stripes or another technology close to it (simple but flexible).
     Overall, I've always preferred component based Web Frameworks to the Actions based ones.

A) GWT and its UI frameworks (more than UI usually)
   GXT and others such as SmartGWT seem to be much slower than raw GWT for rendering but it is expected as the default look and feel looks good without any effort. The default look and feel is cool.

   I stumbled upon GXT buttons rendering. While the buttons are VERY beautiful, the amount of nested elements required for rendering is almost incredible.


1) Normal HTML
<input type="button" value="OK" class='dummyClass' />

2) GXT (dummy example to illustrate the problem)
<table cellspacing="0" role="presentation"
class="x-btn x-component x-btn-noicon" id="x-auto-175"
style="margin-right: 5px;">
  <tbody class="x-btn-small x-btn-icon-small-left">
    <tr>
      <td class="x-btn-tl">
        <i> </i>
      </td>
      <td class="x-btn-tc"></td>
      <td class="x-btn-tr">
        <i> </i>
      </td>
    </tr>
    <tr>
      <td class="x-btn-ml">
        <i> </i>
      </td>
      <td class="x-btn-mc">
        <em unselectable="on" class="">
          <button style="position: relative; width: 69px;"
          type="button" class="x-btn-text" tabindex="0">
          Save</button>
        </em>
      </td>
      <td class="x-btn-mr">
        <i> </i>
      </td>
    </tr>
    <tr>
      <td class="x-btn-bl">
        <i> </i>
      </td>
      <td class="x-btn-bc"></td>
      <td class="x-btn-br">
        <i> </i>
      </td>
    </tr>
  </tbody>
</table>

The above example was taken from http://my.opera.com/lienngoc/blog/2010/08/10/how-to-improve-performance-in-a-gwt-gxt-application and is realistic enough.

B) GWT CellTree
The GWT CellTree is a very nice widget. I managed to use it with RPC calls within a small amount of time and minimal reading.

1) Rendering
I was expecting to be able to provide easily a custom renderer and that was the case. In the GWT showcase, for each level of the tree, the same kind of node is rendered which means a single renderer at each level of the tree. I was like well, it is just an 'example'. In real life, you usually have objects of different kinds at the same level of a tree and they need to be rendered differently.

I ended up using a single renderer and calling instanceof to select the appropriate styling for each node of the tree. I couldn't find another solution within a short amount of time.
public void render(Context context, MyObject value, SafeHtmlBuilder sb) {
 if (value != null) {
  sb.appendHtmlConstant((value instanceof MyBaseObject) ? baseImgHTML : advancedImgHTML).appendEscaped(" ");
  sb.appendHtmlConstant("");
  sb.appendEscaped(value.toString());
  sb.appendHtmlConstant("");
 }
}

2) Can I haz vertical scrollbars???
After testing a simple application, I noticed that Google Chrome was displaying a vertical scrollbar while I was expanding the CellTree nodes. Firefox didn't render any scrollbars.... I came accross a stackoverflow link, and for a second I thought 'this is it!', I guess it would've been too easy...
http://stackoverflow.com/questions/7854086/horizontal-scrollpanel-not-displaying-with-celltree

After 'googling' a bit and Firebug's help, I found a solution.
1. Add few CSS style attributes to the CellTree and its parent container
The celltree has the following CSS style : width:100%;height:100%;overflow:auto. It is enclosed within an HTMLPanel with the same CSS style. There's no need to combine a ScrollPanel with let's say a VerticalPanel. Same problem and additional widgets used.


2. Ensure that the first element has a visible overflow and a dummy size in pixels
I didn't test it with a small tree, but I figure that as long as you supply a dummy size that will always be lower than the height of a non empty tree, it'll be fine. I used 100px.
Style firstCellTreeChildStyle = cellTree.getElement().getFirstChildElement().getStyle();
firstCellTreeChildStyle.setOverflow(Overflow.VISIBLE);
firstCellTreeChildStyle.setHeight(100, Unit.PX);   

C) Overall opinion about pure GWT vs GWT frameworks

It looks like building a professional looking pure GWT application requires a serious commitment in terms of styling widgets. For medium-small applications, I think that using a framework will give good looking results with less time without many performance issues.