]> source.dussan.org Git - vaadin-framework.git/commitdiff
refactoring static methods to Util class, avoiding memory leaks
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Wed, 19 Sep 2007 12:58:52 +0000 (12:58 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Wed, 19 Sep 2007 12:58:52 +0000 (12:58 +0000)
svn changeset:2337/svn branch:trunk

src/com/itmill/toolkit/terminal/gwt/client/Util.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITree.java

index eb99a38c68e7e8e60c510e35eb9115be9f58ac2c..0a93dde18f1a21386fd15d2998ad471909699331 100644 (file)
@@ -1,18 +1,43 @@
 package com.itmill.toolkit.terminal.gwt.client;
 
+import com.google.gwt.user.client.Element;
+
 public class Util {
 
        /**
         * Helper method for debugging purposes.
         * 
         * Stops execution on firefox browsers on a breakpoint.
-        *
+        * 
         */
        public static native void browserDebugger() /*-{
                if(window.console)
                        debugger;
        }-*/;
 
+       /**
+        * Detects if current browser is IE6. Use to isola
+        * 
+        * @return true if IE6
+        */
+       public static native boolean isIE6() /*-{
+               var browser=$wnd.navigator.appName;
+               var version=parseFloat($wnd.navigator.appVersion);
+               if (browser=="Microsoft Internet Explorer" && (version < 7) ) {
+                       return true;
+               }
+               return false;
+       }-*/;
        
-       
+       /**
+        * Nulls oncontextmenu function on given element. We need to manually clear
+        * context menu events due bad browsers memory leaks, since we GWT don't
+        * support them.
+        * 
+        * @param el
+        */
+       public native static void removeContextMenuEvent(Element el) /*-{
+               el.oncontextmenu = null;
+       }-*/;
+
 }
index f13708fadb286f574a330cb9a0638687099664fc..2850641e4c3bf7c0b2acc6bf3b5753fcc302ce4e 100644 (file)
@@ -23,75 +23,75 @@ import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.Util;
 import com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable.IScrollTableBody.IScrollTableRow;
 
 /**
  * Constructor for IScrollTable
  * 
- * IScrollTable is a FlowPanel having two widgets in it:
- *  * TableHead component
- *  * ScrollPanel
- *  
- * TableHead contains table's header and widgets + logic for resizing, 
+ * IScrollTable is a FlowPanel having two widgets in it: * TableHead component *
+ * ScrollPanel
+ * 
+ * TableHead contains table's header and widgets + logic for resizing,
  * reordering and hiding columns.
- *  
- * ScrollPanel contains IScrollTableBody object which handles content.
- * To save some bandwidth and to improve clients responsiviness with
- * loads of data, in IScrollTableBody all rows are not necessarely rendered.
- * There are "spacer" in IScrollTableBody to use the exact same space as
- * unrendered rows would use. This way we can use seamlessly traditional 
- * scrollbars and scrolling to fetch more rows instead of "paging".
- *  
- * In IScrollTable we listen to scroll events. On horizontal scrolling
- * we also update TableHeads scroll position which has its scrollbars 
- * hidden. On vertical scroll events we will check if we are reaching
- * the end of area where we have rows rendered and 
+ * 
+ * ScrollPanel contains IScrollTableBody object which handles content. To save
+ * some bandwidth and to improve clients responsiviness with loads of data, in
+ * IScrollTableBody all rows are not necessarely rendered. There are "spacer" in
+ * IScrollTableBody to use the exact same space as unrendered rows would use.
+ * This way we can use seamlessly traditional scrollbars and scrolling to fetch
+ * more rows instead of "paging".
+ * 
+ * In IScrollTable we listen to scroll events. On horizontal scrolling we also
+ * update TableHeads scroll position which has its scrollbars hidden. On
+ * vertical scroll events we will check if we are reaching the end of area where
+ * we have rows rendered and
  * 
  * TODO implement unregistering for child componts in Cells
  */
-public class IScrollTable extends Composite implements Paintable, ITable, ScrollListener {
-       
+public class IScrollTable extends Composite implements Paintable, ITable,
+               ScrollListener {
+
        public static final String CLASSNAME = "i-table";
        /**
-        *  multiple of pagelenght which component will 
-        *  cache when requesting more rows 
+        * multiple of pagelenght which component will cache when requesting more
+        * rows
         */
        private static final double CACHE_RATE = 2;
-       /** 
-        * fraction of pageLenght which can be scrolled without 
-        * making new request 
+       /**
+        * fraction of pageLenght which can be scrolled without making new request
         */
        private static final double CACHE_REACT_RATE = 1.5;
-       
+
        public static final char ALIGN_CENTER = 'c';
        public static final char ALIGN_LEFT = 'b';
        public static final char ALIGN_RIGHT = 'e';
        private int firstRowInViewPort = 0;
        private int pageLength = 15;
-       
+
        private boolean rowHeaders = false;
-       
+
        private String[] columnOrder;
-       
+
        private ApplicationConnection client;
        private String paintableId;
-       
+
        private boolean immediate;
 
        private int selectMode = ITable.SELECT_MODE_NONE;
 
        private Vector selectedRowKeys = new Vector();
-       
+
        private boolean initializedAndAttached = false;
-       
+
        private TableHead tHead = new TableHead();
 
        private ScrollPanel bodyContainer = new ScrollPanel();
-       
+
        private int totalRows;
-       
+
        private Set collapsedColumns;
-       
+
        private RowRequestHandler rowRequestHandler;
        private IScrollTableBody tBody;
        private String width;
@@ -100,30 +100,28 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
        private boolean sortAscending;
        private String sortColumn;
        private boolean columnReordering;
-       
+
        /**
-        * This map contains captions and icon urls for 
-        * actions like:
-        *   * "33_c" -> "Edit"
-        *   * "33_i" -> "http://dom.com/edit.png"
+        * This map contains captions and icon urls for actions like: * "33_c" ->
+        * "Edit" * "33_i" -> "http://dom.com/edit.png"
         */
        private HashMap actionMap = new HashMap();
        private String[] visibleColOrder;
        private boolean initialContentReceived = false;
        private Element scrollPositionElement;
-       
+
        public IScrollTable() {
-               
+
                bodyContainer.addScrollListener(this);
-               bodyContainer.setStyleName(CLASSNAME+"-body");
-               
+               bodyContainer.setStyleName(CLASSNAME + "-body");
+
                FlowPanel panel = new FlowPanel();
                panel.setStyleName(CLASSNAME);
                panel.add(tHead);
                panel.add(bodyContainer);
-               
+
                rowRequestHandler = new RowRequestHandler();
-               
+
                initWidget(panel);
        }
 
@@ -136,87 +134,89 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                this.immediate = uidl.getBooleanAttribute("immediate");
                this.totalRows = uidl.getIntAttribute("totalrows");
                this.pageLength = uidl.getIntAttribute("pagelength");
-               if(pageLength == 0)
+               if (pageLength == 0)
                        pageLength = totalRows;
-               this.firstvisible = uidl.hasVariable("firstvisible") ? uidl.getIntVariable("firstvisible") : 0;
-               if(uidl.hasAttribute("rowheaders"))
+               this.firstvisible = uidl.hasVariable("firstvisible") ? uidl
+                               .getIntVariable("firstvisible") : 0;
+               if (uidl.hasAttribute("rowheaders"))
                        rowHeaders = true;
-               if(uidl.hasAttribute("width")) {
+               if (uidl.hasAttribute("width")) {
                        width = uidl.getStringAttribute("width");
                }
-               if(uidl.hasAttribute("height"))
+               if (uidl.hasAttribute("height"))
                        height = uidl.getStringAttribute("height");
-               
-               if(uidl.hasVariable("sortascending")) {
+
+               if (uidl.hasVariable("sortascending")) {
                        this.sortAscending = uidl.getBooleanVariable("sortascending");
                        this.sortColumn = uidl.getStringVariable("sortcolumn");
                }
-               
-               if(uidl.hasVariable("selected")) {
+
+               if (uidl.hasVariable("selected")) {
                        Set selectedKeys = uidl.getStringArrayVariableAsSet("selected");
                        selectedRowKeys.clear();
-                       for(Iterator it = selectedKeys.iterator();it.hasNext();)
+                       for (Iterator it = selectedKeys.iterator(); it.hasNext();)
                                selectedRowKeys.add((String) it.next());
                }
-               
-               if(uidl.hasAttribute("selectmode")) {
-                       if(uidl.getStringAttribute("selectmode").equals("multi"))
+
+               if (uidl.hasAttribute("selectmode")) {
+                       if (uidl.getStringAttribute("selectmode").equals("multi"))
                                selectMode = ITable.SELECT_MODE_MULTI;
                        else
                                selectMode = ITable.SELECT_MODE_SINGLE;
                }
-               
-               if(uidl.hasVariable("columnorder")) {
+
+               if (uidl.hasVariable("columnorder")) {
                        this.columnReordering = true;
                        this.columnOrder = uidl.getStringArrayVariable("columnorder");
                }
-               
-               if(uidl.hasVariable("collapsedcolumns")) {
+
+               if (uidl.hasVariable("collapsedcolumns")) {
                        tHead.setColumnCollapsingAllowed(true);
-                       this.collapsedColumns = uidl.getStringArrayVariableAsSet("collapsedcolumns");
+                       this.collapsedColumns = uidl
+                                       .getStringArrayVariableAsSet("collapsedcolumns");
                } else {
                        tHead.setColumnCollapsingAllowed(false);
                }
-               
+
                UIDL rowData = null;
-               for(Iterator it = uidl.getChildIterator(); it.hasNext();) {
+               for (Iterator it = uidl.getChildIterator(); it.hasNext();) {
                        UIDL c = (UIDL) it.next();
-                       if(c.getTag().equals("rows"))
+                       if (c.getTag().equals("rows"))
                                rowData = c;
-                       else if(c.getTag().equals("actions"))
+                       else if (c.getTag().equals("actions"))
                                updateActionMap(c);
-                       else if(c.getTag().equals("visiblecolumns"))
+                       else if (c.getTag().equals("visiblecolumns"))
                                updateVisibleColumns(c);
                }
                updateHeader(uidl.getStringArrayAttribute("vcolorder"));
-               
-               if(initializedAndAttached) {
-                       updateBody(rowData, uidl.getIntAttribute("firstrow"),uidl.getIntAttribute("rows"));
+
+               if (initializedAndAttached) {
+                       updateBody(rowData, uidl.getIntAttribute("firstrow"), uidl
+                                       .getIntAttribute("rows"));
                } else {
-                       getTBody().renderInitialRows(rowData, 
-                                       uidl.getIntAttribute("firstrow"), 
-                                       uidl.getIntAttribute("rows"), 
-                                       totalRows);
+                       getTBody().renderInitialRows(rowData,
+                                       uidl.getIntAttribute("firstrow"),
+                                       uidl.getIntAttribute("rows"), totalRows);
                        bodyContainer.add(tBody);
-                       initialContentReceived  = true;
-                       if(isAttached()) {
+                       initialContentReceived = true;
+                       if (isAttached()) {
                                sizeInit();
                        }
                }
                hideScrollPositionAnnotation();
        }
-       
+
        private void updateVisibleColumns(UIDL uidl) {
                Iterator it = uidl.getChildIterator();
-               while(it.hasNext()) {
+               while (it.hasNext()) {
                        UIDL col = (UIDL) it.next();
                        tHead.updateCellFromUIDL(col);
                }
        }
-       
+
        private IScrollTableBody getTBody() {
-               if(tBody == null || totalRows != tBody.getTotalRows()) {
-                       if(tBody != null)
+               if (tBody == null || totalRows != tBody.getTotalRows()) {
+                       if (tBody != null)
                                tBody.removeFromParent();
                        tBody = new IScrollTableBody();
                }
@@ -225,36 +225,35 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
        private void updateActionMap(UIDL c) {
                Iterator it = c.getChildIterator();
-               while(it.hasNext()) {
+               while (it.hasNext()) {
                        UIDL action = (UIDL) it.next();
                        String key = action.getStringAttribute("key");
                        String caption = action.getStringAttribute("caption");
                        actionMap.put(key + "_c", caption);
-                       if(action.hasAttribute("icon")) {
+                       if (action.hasAttribute("icon")) {
                                // TODO need some uri handling ??
                                actionMap.put(key + "_i", action.getStringAttribute("icon"));
                        }
                }
-               
+
        }
-       
+
        public String getActionCaption(String actionKey) {
                return (String) actionMap.get(actionKey + "_c");
        }
-       
+
        public String getActionIcon(String actionKey) {
                return (String) actionMap.get(actionKey + "_i");
        }
-       
 
        private void updateHeader(String[] strings) {
-               if(strings == null)
+               if (strings == null)
                        return;
 
                int visibleCols = strings.length;
                int colIndex = 0;
-               if(rowHeaders) {
-                       tHead.enableColumn("0",colIndex);
+               if (rowHeaders) {
+                       tHead.enableColumn("0", colIndex);
                        visibleCols++;
                        visibleColOrder = new String[visibleCols];
                        visibleColOrder[colIndex] = "0";
@@ -268,35 +267,40 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        visibleColOrder[colIndex] = cid;
                        tHead.enableColumn(cid, colIndex);
                        colIndex++;
-                       
+
                }
 
        }
-       
+
        /**
-        * @param uidl which contains row data
-        * @param firstRow first row in data set
-        * @param reqRows amount of rows in data set
+        * @param uidl
+        *            which contains row data
+        * @param firstRow
+        *            first row in data set
+        * @param reqRows
+        *            amount of rows in data set
         */
        private void updateBody(UIDL uidl, int firstRow, int reqRows) {
-               if(uidl == null || reqRows < 1)
+               if (uidl == null || reqRows < 1)
                        return;
-               
-               tBody.renderRows(uidl, firstRow, reqRows);
-               
-               int optimalFirstRow = (int) (firstRowInViewPort - pageLength*CACHE_RATE);
-               while(tBody.getFirstRendered() < optimalFirstRow) {
-//                     client.console.log("removing row from start");
-                       tBody.unlinkRow(true);
-               }
-               int optimalLastRow = (int) (firstRowInViewPort + pageLength + pageLength*CACHE_RATE);
-               while(tBody.getLastRendered() > optimalLastRow) {
-//                     client.console.log("removing row from the end");
-                       tBody.unlinkRow(false);
-               }
-               
+
+               tBody.renderRows(uidl, firstRow, reqRows);
+
+               int optimalFirstRow = (int) (firstRowInViewPort - pageLength
+                               * CACHE_RATE);
+               while (tBody.getFirstRendered() < optimalFirstRow) {
+                       // client.console.log("removing row from start");
+                       tBody.unlinkRow(true);
+               }
+               int optimalLastRow = (int) (firstRowInViewPort + pageLength + pageLength
+                               * CACHE_RATE);
+               while (tBody.getLastRendered() > optimalLastRow) {
+                       // client.console.log("removing row from the end");
+                       tBody.unlinkRow(false);
+               }
+
        }
-       
+
        /**
         * Gives correct column index for given column key ("cid" in UIDL).
         * 
@@ -305,19 +309,19 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
         */
        private int getColIndexByKey(String colKey) {
                // return 0 if asked for rowHeaders
-               if("0".equals(colKey))
+               if ("0".equals(colKey))
                        return 0;
                for (int i = 0; i < visibleColOrder.length; i++) {
-                       if(visibleColOrder[i].equals(colKey))
+                       if (visibleColOrder[i].equals(colKey))
                                return i;
                }
                return -1;
        }
-       
+
        private boolean isCollapsedColumn(String colKey) {
-               if(collapsedColumns == null)
+               if (collapsedColumns == null)
                        return false;
-               if(collapsedColumns.contains(colKey))
+               if (collapsedColumns.contains(colKey))
                        return true;
                return false;
        }
@@ -330,65 +334,66 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                HeaderCell cell = tHead.getHeaderCell(colIndex);
                cell.setWidth(w);
                tBody.setColWidth(colIndex, w);
-               String cid = cell.getColKey();;
+               String cid = cell.getColKey();
+               ;
        }
-       
+
        private int getColWidth(String colKey) {
                return tHead.getHeaderCell(colKey).getWidth();
        }
-       
+
        private IScrollTableRow getRenderedRowByKey(String key) {
                Iterator it = tBody.iterator();
                IScrollTableRow r = null;
-               while(it.hasNext()) {
+               while (it.hasNext()) {
                        r = (IScrollTableRow) it.next();
-                       if(r.getKey().equals(key))
+                       if (r.getKey().equals(key))
                                return r;
                }
                return null;
        }
-       
+
        private int getRenderedRowCount() {
-               return tBody.getLastRendered()-tBody.getFirstRendered();
+               return tBody.getLastRendered() - tBody.getFirstRendered();
        }
-       
+
        private void reOrderColumn(String columnKey, int newIndex) {
-               
+
                int oldIndex = getColIndexByKey(columnKey);
-               
+
                // Change header order
                tHead.moveCell(oldIndex, newIndex);
 
                // Change body order
                tBody.moveCol(oldIndex, newIndex);
-               
-               /* Build new columnOrder and update it to server
-                * Note that columnOrder also contains collapsed columns
-                * so we cannot directly build it from cells vector
-                * Loop the old columnOrder and append in order to new array 
-                * unless on moved columnKey. On new index also put the moved key
+
+               /*
+                * Build new columnOrder and update it to server Note that columnOrder
+                * also contains collapsed columns so we cannot directly build it from
+                * cells vector Loop the old columnOrder and append in order to new
+                * array unless on moved columnKey. On new index also put the moved key
                 * i == index on columnOrder, j == index on newOrder
                 */
                String oldKeyOnNewIndex = visibleColOrder[newIndex];
-               if(rowHeaders)
+               if (rowHeaders)
                        newIndex--; // columnOrder don't have rowHeader
-               // add back hidden rows, 
+               // add back hidden rows,
                for (int i = 0; i < columnOrder.length; i++) {
-                       if(columnOrder[i].equals(oldKeyOnNewIndex))
+                       if (columnOrder[i].equals(oldKeyOnNewIndex))
                                break; // break loop at target
-                       if(isCollapsedColumn(columnOrder[i]))
+                       if (isCollapsedColumn(columnOrder[i]))
                                newIndex++;
                }
                // finally we can build the new columnOrder for server
                String[] newOrder = new String[columnOrder.length];
-               for(int i = 0, j = 0; j < newOrder.length; i++) {
-                       if(j == newIndex) {
+               for (int i = 0, j = 0; j < newOrder.length; i++) {
+                       if (j == newIndex) {
                                newOrder[j] = columnKey;
                                j++;
                        }
-                       if(i == columnOrder.length)
+                       if (i == columnOrder.length)
                                break;
-                       if(columnOrder[i].equals(columnKey))
+                       if (columnOrder[i].equals(columnKey))
                                continue;
                        newOrder[j] = columnOrder[i];
                        j++;
@@ -398,7 +403,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                int i = rowHeaders ? 1 : 0;
                for (int j = 0; j < newOrder.length; j++) {
                        String cid = newOrder[j];
-                       if(!isCollapsedColumn(cid))
+                       if (!isCollapsedColumn(cid))
                                visibleColOrder[i++] = cid;
                }
                client.updateVariable(paintableId, "columnorder", columnOrder, false);
@@ -406,28 +411,27 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
        protected void onAttach() {
                super.onAttach();
-               if(initialContentReceived) {
+               if (initialContentReceived) {
                        sizeInit();
                }
        }
 
        protected void onDetach() {
                super.onDetach();
-               //ensure that scrollPosElement will be detached
-               if(scrollPositionElement != null) {
+               // ensure that scrollPosElement will be detached
+               if (scrollPositionElement != null) {
                        Element parent = DOM.getParent(scrollPositionElement);
-                       if(parent != null)
+                       if (parent != null)
                                DOM.removeChild(parent, scrollPositionElement);
                }
        }
 
        /**
         * Run only once when component is attached and received its initial
-        * content. This function :
-        *  * Syncs headers and bodys "natural widths and saves the values.
-        *  * Sets proper width and height
-        *  * Makes deferred request to get some cache rows
-       */
+        * content. This function : * Syncs headers and bodys "natural widths and
+        * saves the values. * Sets proper width and height * Makes deferred request
+        * to get some cache rows
+        */
        private void sizeInit() {
                /*
                 * We will use browsers table rendering algorithm to find proper column
@@ -442,19 +446,20 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                int i = 0;
                int totalExplicitColumnsWidths = 0;
                int total = 0;
-               
+
                int[] widths = new int[tHead.visibleCells.size()];
-               
+
                // first loop: collect natural widths
-               while(headCells.hasNext()) {
+               while (headCells.hasNext()) {
                        HeaderCell hCell = (HeaderCell) headCells.next();
                        int w;
-                       if(hCell.getWidth() > 0) {
+                       if (hCell.getWidth() > 0) {
                                // server has defined column width explicitly
                                w = hCell.getWidth();
                                totalExplicitColumnsWidths += w;
                        } else {
-                               int hw = DOM.getElementPropertyInt(hCell.getElement(), "offsetWidth");
+                               int hw = DOM.getElementPropertyInt(hCell.getElement(),
+                                               "offsetWidth");
                                int cw = tBody.getColWidth(i);
                                w = (hw > cw ? hw : cw) + IScrollTableBody.CELL_EXTRA_WIDTH;
                        }
@@ -465,48 +470,49 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
                tHead.disableBrowserIntelligence();
 
-               if(height == null) {
-                       bodyContainer.setHeight((tBody.getRowHeight()*pageLength) + "px");
+               if (height == null) {
+                       bodyContainer.setHeight((tBody.getRowHeight() * pageLength) + "px");
                } else {
                        bodyContainer.setHeight(height);
                }
 
-               if(width == null) {
+               if (width == null) {
                        int w = total;
                        w += getScrollbarWidth();
                        bodyContainer.setWidth(w + "px");
                        tHead.setWidth(w + "px");
                        this.setWidth(w + "px");
                } else {
-                       if(width.indexOf("px") > 0) {
+                       if (width.indexOf("px") > 0) {
                                bodyContainer.setWidth(width);
                                tHead.setWidth(width);
                                this.setWidth(width);
-                       } else if(width.indexOf("%") > 0) {
+                       } else if (width.indexOf("%") > 0) {
                                this.setWidth(width);
                                // contained blocks are relative to parents
                                bodyContainer.setWidth("100%");
                                tHead.setWidth("100%");
-                               
+
                        }
                }
-               
+
                int availW = tBody.getAvailableWidth();
 
-               if(availW > total) {
+               if (availW > total) {
                        // natural size is smaller than available space
-                       int extraSpace = availW -total;
+                       int extraSpace = availW - total;
                        int totalWidthR = total - totalExplicitColumnsWidths;
-                       if(totalWidthR > 0) {
-                               // now we will share this sum relatively to those without explicit width
+                       if (totalWidthR > 0) {
+                               // now we will share this sum relatively to those without
+                               // explicit width
                                headCells = tHead.iterator();
                                i = 0;
                                HeaderCell hCell;
-                               while(headCells.hasNext()) {
+                               while (headCells.hasNext()) {
                                        hCell = (HeaderCell) headCells.next();
-                                       if(hCell.getWidth() == -1) {
+                                       if (hCell.getWidth() == -1) {
                                                int w = widths[i];
-                                               int newSpace = extraSpace*w/totalWidthR;
+                                               int newSpace = extraSpace * w / totalWidthR;
                                                w += newSpace;
                                                widths[i] = w;
                                        }
@@ -520,26 +526,29 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                // last loop: set possibly modified values
                i = 0;
                headCells = tHead.iterator();
-               while(headCells.hasNext()) {
+               while (headCells.hasNext()) {
                        HeaderCell hCell = (HeaderCell) headCells.next();
-                       if(hCell.getWidth() == -1) {
+                       if (hCell.getWidth() == -1) {
                                int w = widths[i];
-                               setColWidth(i , w);
+                               setColWidth(i, w);
                        }
                        i++;
                }
 
-               if(firstvisible > 0) {
-                       bodyContainer.setScrollPosition(firstvisible*tBody.getRowHeight());
+               if (firstvisible > 0) {
+                       bodyContainer
+                                       .setScrollPosition(firstvisible * tBody.getRowHeight());
                        firstRowInViewPort = firstvisible;
                }
-               
+
                DeferredCommand.addCommand(new Command() {
                        public void execute() {
-                               if(totalRows - 1 > tBody.getLastRendered()) {
+                               if (totalRows - 1 > tBody.getLastRendered()) {
                                        // fetch cache rows
-                                       rowRequestHandler.setReqFirstRow(tBody.getLastRendered()+1);
-                                       rowRequestHandler.setReqRows((int) (pageLength*CACHE_RATE));
+                                       rowRequestHandler
+                                                       .setReqFirstRow(tBody.getLastRendered() + 1);
+                                       rowRequestHandler
+                                                       .setReqRows((int) (pageLength * CACHE_RATE));
                                        rowRequestHandler.deferRowFetch();
                                }
                        }
@@ -548,115 +557,134 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
        }
 
        private int getScrollbarWidth() {
-               return bodyContainer.getOffsetWidth() - 
-                       DOM.getElementPropertyInt(bodyContainer.getElement(), "clientWidth");
+               return bodyContainer.getOffsetWidth()
+                               - DOM.getElementPropertyInt(bodyContainer.getElement(),
+                                               "clientWidth");
        }
 
        /**
-        * This method has logick which rows needs to be requested from
-        * server when user scrolls
-        *
+        * This method has logick which rows needs to be requested from server when
+        * user scrolls
+        * 
         */
        public void onScroll(Widget widget, int scrollLeft, int scrollTop) {
-               if(!initializedAndAttached)
+               if (!initializedAndAttached)
                        return;
-               
+
                rowRequestHandler.cancel();
-               
+
                // fix headers horizontal scrolling
                tHead.setHorizontalScrollPosition(scrollLeft);
-       
-               firstRowInViewPort = (int) Math.ceil( scrollTop / (double) tBody.getRowHeight() );
-               ApplicationConnection.getConsole()
-                       .log("At scrolltop: " + scrollTop + " At row " + firstRowInViewPort);
-               
-               int postLimit = (int) (firstRowInViewPort + pageLength + pageLength*CACHE_REACT_RATE);
-               if(postLimit > totalRows -1 )
+
+               firstRowInViewPort = (int) Math.ceil(scrollTop
+                               / (double) tBody.getRowHeight());
+               ApplicationConnection.getConsole().log(
+                               "At scrolltop: " + scrollTop + " At row " + firstRowInViewPort);
+
+               int postLimit = (int) (firstRowInViewPort + pageLength + pageLength
+                               * CACHE_REACT_RATE);
+               if (postLimit > totalRows - 1)
                        postLimit = totalRows - 1;
-               int preLimit = (int) (firstRowInViewPort - pageLength*CACHE_REACT_RATE);
-               if(preLimit < 0)
+               int preLimit = (int) (firstRowInViewPort - pageLength
+                               * CACHE_REACT_RATE);
+               if (preLimit < 0)
                        preLimit = 0;
                int lastRendered = tBody.getLastRendered();
                int firstRendered = tBody.getFirstRendered();
-               
-               if( postLimit <= lastRendered && preLimit >= firstRendered ) {
-                       client.updateVariable(this.paintableId, "firstvisible", firstRowInViewPort, false);
+
+               if (postLimit <= lastRendered && preLimit >= firstRendered) {
+                       client.updateVariable(this.paintableId, "firstvisible",
+                                       firstRowInViewPort, false);
                        return; // scrolled withing "non-react area"
                }
-               
-               if(firstRowInViewPort - pageLength*CACHE_RATE > lastRendered ||
-                               firstRowInViewPort + pageLength + pageLength*CACHE_RATE < firstRendered ) {
+
+               if (firstRowInViewPort - pageLength * CACHE_RATE > lastRendered
+                               || firstRowInViewPort + pageLength + pageLength * CACHE_RATE < firstRendered) {
                        // need a totally new set
-                       ApplicationConnection.getConsole().log("Table: need a totally new set");
-                       rowRequestHandler.setReqFirstRow((int) (firstRowInViewPort - pageLength*CACHE_RATE));
-                       rowRequestHandler.setReqRows((int) (2*CACHE_RATE*pageLength + pageLength));
+                       ApplicationConnection.getConsole().log(
+                                       "Table: need a totally new set");
+                       rowRequestHandler
+                                       .setReqFirstRow((int) (firstRowInViewPort - pageLength
+                                                       * CACHE_RATE));
+                       rowRequestHandler
+                                       .setReqRows((int) (2 * CACHE_RATE * pageLength + pageLength));
                        rowRequestHandler.deferRowFetch();
                        return;
                }
-               if(preLimit < firstRendered ) {
+               if (preLimit < firstRendered) {
                        // need some rows to the beginning of the rendered area
-                       ApplicationConnection.getConsole().log("Table: need some rows to the beginning of the rendered area");
-                       rowRequestHandler.setReqFirstRow((int) (firstRowInViewPort - pageLength*CACHE_RATE));
-                       rowRequestHandler.setReqRows(firstRendered - rowRequestHandler.getReqFirstRow());
+                       ApplicationConnection
+                                       .getConsole()
+                                       .log(
+                                                       "Table: need some rows to the beginning of the rendered area");
+                       rowRequestHandler
+                                       .setReqFirstRow((int) (firstRowInViewPort - pageLength
+                                                       * CACHE_RATE));
+                       rowRequestHandler.setReqRows(firstRendered
+                                       - rowRequestHandler.getReqFirstRow());
                        rowRequestHandler.deferRowFetch();
-       
+
                        return;
                }
-               if(postLimit > lastRendered) {
+               if (postLimit > lastRendered) {
                        // need some rows to the end of the rendered area
-                       ApplicationConnection.getConsole().log("need some rows to the end of the rendered area");
+                       ApplicationConnection.getConsole().log(
+                                       "need some rows to the end of the rendered area");
                        rowRequestHandler.setReqFirstRow(lastRendered + 1);
-                       rowRequestHandler.setReqRows((int) ((firstRowInViewPort + pageLength + pageLength*CACHE_RATE) - lastRendered));
+                       rowRequestHandler.setReqRows((int) ((firstRowInViewPort
+                                       + pageLength + pageLength * CACHE_RATE) - lastRendered));
                        rowRequestHandler.deferRowFetch();
                }
-               
+
        }
 
        private void announceScrollPosition() {
-               ApplicationConnection.getConsole().log(""+firstRowInViewPort);
-               if(scrollPositionElement == null) {
+               ApplicationConnection.getConsole().log("" + firstRowInViewPort);
+               if (scrollPositionElement == null) {
                        scrollPositionElement = DOM.createDiv();
-                       DOM.setElementProperty(scrollPositionElement, "className", "i-table-scrollposition");
-                       DOM.appendChild(RootPanel.get().getElement(), scrollPositionElement);
+                       DOM.setElementProperty(scrollPositionElement, "className",
+                                       "i-table-scrollposition");
+                       DOM
+                                       .appendChild(RootPanel.get().getElement(),
+                                                       scrollPositionElement);
                }
-               
-               
+
                DOM.setStyleAttribute(scrollPositionElement, "left",
-                               (
-                                               DOM.getAbsoluteLeft(getElement()) +
-                                               DOM.getElementPropertyInt(getElement(), "offsetWidth")/2 
-                                               - 75
-                               )  + "px");
-               DOM.setStyleAttribute(scrollPositionElement, "top",
-                               (
-                                               DOM.getAbsoluteTop(getElement())
-                               )  + "px");
-               
+                               (DOM.getAbsoluteLeft(getElement())
+                                               + DOM
+                                                               .getElementPropertyInt(getElement(),
+                                                                               "offsetWidth") / 2 - 75)
+                                               + "px");
+               DOM.setStyleAttribute(scrollPositionElement, "top", (DOM
+                               .getAbsoluteTop(getElement()))
+                               + "px");
+
                int last = (firstRowInViewPort + pageLength);
-               if(last > totalRows)
+               if (last > totalRows)
                        last = totalRows;
-               DOM.setInnerHTML(scrollPositionElement, 
-                               firstRowInViewPort + " - " + last + "...");
+               DOM.setInnerHTML(scrollPositionElement, firstRowInViewPort + " - "
+                               + last + "...");
                DOM.setStyleAttribute(scrollPositionElement, "display", "block");
        }
-       
+
        private void hideScrollPositionAnnotation() {
-               if(scrollPositionElement != null)
+               if (scrollPositionElement != null)
                        DOM.setStyleAttribute(scrollPositionElement, "display", "none");
        }
-       
+
        private class RowRequestHandler extends Timer {
-               
+
                private int reqFirstRow = 0;
                private int reqRows = 0;
-               
+
                public void deferRowFetch() {
-                       if(reqRows > 0 && reqFirstRow < totalRows) {
+                       if (reqRows > 0 && reqFirstRow < totalRows) {
                                schedule(250);
-                               
-                               // tell scroll position to user if currently "visible"  rows are not rendered
-                               if( (firstRowInViewPort + pageLength > tBody.getLastRendered()) ||
-                                               (firstRowInViewPort <  tBody.getFirstRendered())) {
+
+                               // tell scroll position to user if currently "visible" rows are
+                               // not rendered
+                               if ((firstRowInViewPort + pageLength > tBody.getLastRendered())
+                                               || (firstRowInViewPort < tBody.getFirstRendered())) {
                                        announceScrollPosition();
                                } else {
                                        hideScrollPositionAnnotation();
@@ -665,9 +693,9 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                }
 
                public void setReqFirstRow(int reqFirstRow) {
-                       if(reqFirstRow < 0)
+                       if (reqFirstRow < 0)
                                reqFirstRow = 0;
-                       else if(reqFirstRow >= totalRows)
+                       else if (reqFirstRow >= totalRows)
                                reqFirstRow = totalRows - 1;
                        this.reqFirstRow = reqFirstRow;
                }
@@ -677,9 +705,12 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                }
 
                public void run() {
-                       ApplicationConnection.getConsole().log("Getting " + reqRows + " rows from " + reqFirstRow);
-                       client.updateVariable(paintableId, "firstvisible", firstRowInViewPort, false);
-                       client.updateVariable(paintableId, "reqfirstrow", reqFirstRow, false);
+                       ApplicationConnection.getConsole().log(
+                                       "Getting " + reqRows + " rows from " + reqFirstRow);
+                       client.updateVariable(paintableId, "firstvisible",
+                                       firstRowInViewPort, false);
+                       client.updateVariable(paintableId, "reqfirstrow", reqFirstRow,
+                                       false);
                        client.updateVariable(paintableId, "reqrows", reqRows, true);
                }
 
@@ -695,9 +726,9 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                 * Sends request to refresh content at this position.
                 */
                public void refreshContent() {
-                       int first = (int) (firstRowInViewPort - pageLength*CACHE_RATE);
-                       int reqRows = (int) (2*pageLength*CACHE_RATE + pageLength);
-                       if(first < 0) {
+                       int first = (int) (firstRowInViewPort - pageLength * CACHE_RATE);
+                       int reqRows = (int) (2 * pageLength * CACHE_RATE + pageLength);
+                       if (first < 0) {
                                reqRows = reqRows + first;
                                first = 0;
                        }
@@ -706,25 +737,25 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        run();
                }
        }
-       
+
        public class HeaderCell extends Widget {
-               
+
                private static final int DRAG_WIDGET_WIDTH = 2;
-               
+
                private static final int MINIMUM_COL_WIDTH = 20;
 
                Element td = DOM.createTD();
 
                Element captionContainer = DOM.createDiv();
-               
+
                Element colResizeWidget = DOM.createDiv();
-               
+
                Element floatingCopyOfHeaderCell;
-               
+
                private boolean sortable = false;
                private String cid;
                private boolean dragging;
-               
+
                private int dragStartX;
                private int colIndex;
                private int originalWidth;
@@ -741,53 +772,60 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
                private char align = ALIGN_LEFT;
 
-               private HeaderCell(){};
-               
+               private HeaderCell() {
+               };
+
                public void setSortable(boolean b) {
                        sortable = b;
                }
-               
+
                public HeaderCell(String colId, String headerText) {
                        this.cid = colId;
-                       
-                       DOM.setElementProperty(colResizeWidget, "className", CLASSNAME+"-resizer");
-                       DOM.setStyleAttribute(colResizeWidget, "width",  DRAG_WIDGET_WIDTH +"px");
+
+                       DOM.setElementProperty(colResizeWidget, "className", CLASSNAME
+                                       + "-resizer");
+                       DOM.setStyleAttribute(colResizeWidget, "width", DRAG_WIDGET_WIDTH
+                                       + "px");
                        DOM.sinkEvents(colResizeWidget, Event.MOUSEEVENTS);
-                       
+
                        setText(headerText);
-                       
+
                        DOM.appendChild(td, colResizeWidget);
-                       
-                       DOM.setElementProperty(captionContainer, "className", CLASSNAME+"-caption-container");
+
+                       DOM.setElementProperty(captionContainer, "className", CLASSNAME
+                                       + "-caption-container");
                        DOM.sinkEvents(captionContainer, Event.MOUSEEVENTS);
 
                        DOM.appendChild(td, captionContainer);
-                       
+
                        DOM.sinkEvents(td, Event.MOUSEEVENTS);
-                       
+
                        setElement(td);
                }
-               
+
                public void setWidth(int w) {
                        this.width = w;
-                       DOM.setStyleAttribute(captionContainer, "width", (w - DRAG_WIDGET_WIDTH - 4) + "px");
+                       DOM.setStyleAttribute(captionContainer, "width", (w
+                                       - DRAG_WIDGET_WIDTH - 4)
+                                       + "px");
                        setWidth(w + "px");
                }
-               
+
                public int getWidth() {
                        return width;
                }
-               
+
                public void setText(String headerText) {
                        DOM.setInnerHTML(captionContainer, headerText);
                }
+
                public String getColKey() {
                        return cid;
                }
-               
+
                private void setSorted(boolean sorted) {
-                       if(sorted) {
-                               if(sortAscending)
+                       if (sorted) {
+                               if (sortAscending)
                                        this.setStyleName("header-cell-asc");
                                else
                                        this.setStyleName("header-cell-desc");
@@ -800,7 +838,8 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                 * Handle column reordering.
                 */
                public void onBrowserEvent(Event event) {
-                       if(isResizing || DOM.compare(DOM.eventGetTarget(event), colResizeWidget)) {
+                       if (isResizing
+                                       || DOM.compare(DOM.eventGetTarget(event), colResizeWidget)) {
                                onResizeEvent(event);
                        } else {
                                handleCaptionEvent(event);
@@ -808,55 +847,68 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        super.onBrowserEvent(event);
                }
 
-               
                private void createFloatingCopy() {
                        floatingCopyOfHeaderCell = DOM.createDiv();
                        DOM.setInnerHTML(floatingCopyOfHeaderCell, DOM.getInnerHTML(td));
-                       floatingCopyOfHeaderCell = DOM.getChild(floatingCopyOfHeaderCell, 1);
+                       floatingCopyOfHeaderCell = DOM
+                                       .getChild(floatingCopyOfHeaderCell, 1);
                        // TODO isolate non-standard css attribute (filter)
                        // TODO move styles to css file
-                       DOM.setElementProperty(floatingCopyOfHeaderCell, "className", CLASSNAME+"-header-drag");
-                       updateFloatingCopysPosition(DOM.getAbsoluteLeft(td), DOM.getAbsoluteTop(td));
-                       DOM.appendChild(RootPanel.get().getElement(), floatingCopyOfHeaderCell);
+                       DOM.setElementProperty(floatingCopyOfHeaderCell, "className",
+                                       CLASSNAME + "-header-drag");
+                       updateFloatingCopysPosition(DOM.getAbsoluteLeft(td), DOM
+                                       .getAbsoluteTop(td));
+                       DOM.appendChild(RootPanel.get().getElement(),
+                                       floatingCopyOfHeaderCell);
                }
-               
+
                private void updateFloatingCopysPosition(int x, int y) {
-                       x -= DOM.getElementPropertyInt(floatingCopyOfHeaderCell, "offsetWidth")/2;
+                       x -= DOM.getElementPropertyInt(floatingCopyOfHeaderCell,
+                                       "offsetWidth") / 2;
                        DOM.setStyleAttribute(floatingCopyOfHeaderCell, "left", x + "px");
-                       if(y > 0)
-                               DOM.setStyleAttribute(floatingCopyOfHeaderCell, "top", (y + 7) + "px");
+                       if (y > 0)
+                               DOM.setStyleAttribute(floatingCopyOfHeaderCell, "top", (y + 7)
+                                               + "px");
                }
-               
+
                private void hideFloatingCopy() {
-                       DOM.removeChild(RootPanel.get().getElement(), floatingCopyOfHeaderCell);
+                       DOM.removeChild(RootPanel.get().getElement(),
+                                       floatingCopyOfHeaderCell);
                        floatingCopyOfHeaderCell = null;
                }
-               
+
                protected void handleCaptionEvent(Event event) {
                        switch (DOM.eventGetType(event)) {
                        case Event.ONMOUSEDOWN:
-                               ApplicationConnection.getConsole().log("HeaderCaption: mouse down");
-                               if(columnReordering) {
+                               ApplicationConnection.getConsole().log(
+                                               "HeaderCaption: mouse down");
+                               if (columnReordering) {
                                        dragging = true;
                                        moved = false;
-                               colIndex = getColIndexByKey(cid);
+                                       colIndex = getColIndexByKey(cid);
                                        DOM.setCapture(getElement());
                                        this.headerX = tHead.getAbsoluteLeft();
-                                       ApplicationConnection.getConsole().log("HeaderCaption: Caption set to capture mouse events");
+                                       ApplicationConnection
+                                                       .getConsole()
+                                                       .log(
+                                                                       "HeaderCaption: Caption set to capture mouse events");
                                        DOM.eventPreventDefault(event); // prevent selecting text
                                }
                                break;
                        case Event.ONMOUSEUP:
-                               ApplicationConnection.getConsole().log("HeaderCaption: mouseUP");
-                               if(columnReordering) {
+                               ApplicationConnection.getConsole()
+                                               .log("HeaderCaption: mouseUP");
+                               if (columnReordering) {
                                        dragging = false;
                                        DOM.releaseCapture(getElement());
-                                       ApplicationConnection.getConsole().log("HeaderCaption: Stopped column reordering");
-                                       if(moved) {
+                                       ApplicationConnection.getConsole().log(
+                                                       "HeaderCaption: Stopped column reordering");
+                                       if (moved) {
                                                hideFloatingCopy();
                                                tHead.removeSlotFocus();
-                                               if(closestSlot != colIndex &&  closestSlot != (colIndex + 1) ) {
-                                                       if(closestSlot > colIndex)
+                                               if (closestSlot != colIndex
+                                                               && closestSlot != (colIndex + 1)) {
+                                                       if (closestSlot > colIndex)
                                                                reOrderColumn(cid, closestSlot - 1);
                                                        else
                                                                reOrderColumn(cid, closestSlot);
@@ -864,21 +916,24 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                        }
                                }
 
-                               if(!moved) {
+                               if (!moved) {
                                        // mouse event was a click to header -> sort column
-                                       if(sortable) {
-                                               if(sortColumn.equals(cid)) {
+                                       if (sortable) {
+                                               if (sortColumn.equals(cid)) {
                                                        // just toggle order
-                                                       client.updateVariable(paintableId, "sortascending", !sortAscending, false);
+                                                       client.updateVariable(paintableId, "sortascending",
+                                                                       !sortAscending, false);
                                                } else {
                                                        // set table scrolled by this column
-                                                       client.updateVariable(paintableId, "sortcolumn", cid, false);
+                                                       client.updateVariable(paintableId, "sortcolumn",
+                                                                       cid, false);
                                                }
                                                // get also cache columns at the same request
                                                bodyContainer.setScrollPosition(0);
                                                firstvisible = 0;
                                                rowRequestHandler.setReqFirstRow(0);
-                                               rowRequestHandler.setReqRows((int) (2*pageLength*CACHE_RATE + pageLength));
+                                               rowRequestHandler.setReqRows((int) (2 * pageLength
+                                                               * CACHE_RATE + pageLength));
                                                rowRequestHandler.deferRowFetch();
                                        }
                                        break;
@@ -886,8 +941,9 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                break;
                        case Event.ONMOUSEMOVE:
                                if (dragging) {
-                                       ApplicationConnection.getConsole().log("HeaderCaption: Dragging column, optimal index...");
-                                       if(!moved) {
+                                       ApplicationConnection.getConsole().log(
+                                                       "HeaderCaption: Dragging column, optimal index...");
+                                       if (!moved) {
                                                createFloatingCopy();
                                                moved = true;
                                        }
@@ -896,61 +952,61 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                        closestSlot = colIndex;
                                        int closestDistance = -1;
                                        int start = 0;
-                                       if(rowHeaders) {
+                                       if (rowHeaders) {
                                                start++;
                                        }
                                        int visibleCellCount = tHead.getVisibleCellCount();
-                                       for(int i = start; i <= visibleCellCount ; i++ ) {
-                                               if(i > 0) {
-                                                       String colKey = getColKeyByIndex(i-1);
+                                       for (int i = start; i <= visibleCellCount; i++) {
+                                               if (i > 0) {
+                                                       String colKey = getColKeyByIndex(i - 1);
                                                        slotX += getColWidth(colKey);
                                                }
                                                int dist = Math.abs(x - slotX);
-                                               if(closestDistance == -1 || dist < closestDistance) {
+                                               if (closestDistance == -1 || dist < closestDistance) {
                                                        closestDistance = dist;
                                                        closestSlot = i;
                                                }
                                        }
                                        tHead.focusSlot(closestSlot);
-                                       
+
                                        updateFloatingCopysPosition(x, -1);
-                                       ApplicationConnection.getConsole().log(""+closestSlot);
+                                       ApplicationConnection.getConsole().log("" + closestSlot);
                                }
                                break;
                        default:
                                break;
                        }
                }
-               
+
                private void onResizeEvent(Event event) {
-                   switch (DOM.eventGetType(event)) {
-                       case Event.ONMOUSEDOWN:
-                                   isResizing = true;
-                                   DOM.setCapture(getElement());
-                                   dragStartX = DOM.eventGetClientX(event);
-                               colIndex = getColIndexByKey(cid);
-                               originalWidth = getWidth();
-                               DOM.eventPreventDefault(event);
-                               break;
-                       case Event.ONMOUSEUP:
-                               isResizing = false;
-                                   DOM.releaseCapture(getElement());
-                               break;
-                       case Event.ONMOUSEMOVE:
-                                   if (isResizing) {
-                                       int deltaX = DOM.eventGetClientX(event) - dragStartX ;
-                                       if(deltaX == 0)
-                                               return;
-                                       
-                                       int newWidth = originalWidth + deltaX;
-                                       if(newWidth < MINIMUM_COL_WIDTH)
-                                               newWidth = MINIMUM_COL_WIDTH;
-                                       setColWidth(colIndex, newWidth);
-                                     }
-                               break;
-                       default:
-                               break;
-                   }
+                       switch (DOM.eventGetType(event)) {
+                       case Event.ONMOUSEDOWN:
+                               isResizing = true;
+                               DOM.setCapture(getElement());
+                               dragStartX = DOM.eventGetClientX(event);
+                               colIndex = getColIndexByKey(cid);
+                               originalWidth = getWidth();
+                               DOM.eventPreventDefault(event);
+                               break;
+                       case Event.ONMOUSEUP:
+                               isResizing = false;
+                               DOM.releaseCapture(getElement());
+                               break;
+                       case Event.ONMOUSEMOVE:
+                               if (isResizing) {
+                                       int deltaX = DOM.eventGetClientX(event) - dragStartX;
+                                       if (deltaX == 0)
+                                               return;
+
+                                       int newWidth = originalWidth + deltaX;
+                                       if (newWidth < MINIMUM_COL_WIDTH)
+                                               newWidth = MINIMUM_COL_WIDTH;
+                                       setColWidth(colIndex, newWidth);
+                               }
+                               break;
+                       default:
+                               break;
+                       }
                }
 
                public String getCaption() {
@@ -962,13 +1018,15 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                }
 
                public void setAlign(char c) {
-                       if(align  != c) {
-                               switch(c) {
+                       if (align != c) {
+                               switch (c) {
                                case ALIGN_CENTER:
-                                       DOM.setStyleAttribute(captionContainer, "textAlign", "center");
+                                       DOM.setStyleAttribute(captionContainer, "textAlign",
+                                                       "center");
                                        break;
                                case ALIGN_RIGHT:
-                                       DOM.setStyleAttribute(captionContainer, "textAlign", "right");
+                                       DOM.setStyleAttribute(captionContainer, "textAlign",
+                                                       "right");
                                        break;
                                default:
                                        DOM.setStyleAttribute(captionContainer, "textAlign", "");
@@ -982,16 +1040,15 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        return align;
                }
 
-
        }
-       
+
        /**
         * HeaderCell that is header cell for row headers.
         * 
         * Reordering disabled and clicking on it resets sorting.
         */
        public class RowHeadersHeaderCell extends HeaderCell {
-               
+
                RowHeadersHeaderCell() {
                        super("0", "");
                }
@@ -1001,15 +1058,15 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        // TODO It'd be nice to reset sorting here
                }
        }
-       
+
        public class TableHead extends Panel implements IActionOwner {
-               
+
                private static final int WRAPPER_WIDTH = 9000;
-               
+
                Vector visibleCells = new Vector();
-               
+
                HashMap availableCells = new HashMap();
-               
+
                Element div = DOM.createDiv();
                Element hTableWrapper = DOM.createDiv();
                Element hTableContainer = DOM.createDiv();
@@ -1020,17 +1077,19 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                private Element columnSelector = DOM.createDiv();
 
                private int focusedSlot = -1;
-               
+
                private boolean columnCollapsing = false;
-               
+
                public TableHead() {
                        DOM.setStyleAttribute(hTableWrapper, "overflow", "hidden");
-                       DOM.setElementProperty(hTableWrapper, "className", CLASSNAME+"-header");
+                       DOM.setElementProperty(hTableWrapper, "className", CLASSNAME
+                                       + "-header");
 
                        // TODO move styles to CSS
-                       DOM.setElementProperty(columnSelector, "className", CLASSNAME+"-column-selector");
+                       DOM.setElementProperty(columnSelector, "className", CLASSNAME
+                                       + "-column-selector");
                        DOM.setStyleAttribute(columnSelector, "display", "none");
-                       
+
                        DOM.appendChild(table, headerTableBody);
                        DOM.appendChild(headerTableBody, tr);
                        DOM.appendChild(hTableContainer, table);
@@ -1038,39 +1097,36 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        DOM.appendChild(div, columnSelector);
                        DOM.appendChild(div, hTableWrapper);
                        setElement(div);
-                       
-                       setStyleName(CLASSNAME+"-header-wrap");
-                       
+
+                       setStyleName(CLASSNAME + "-header-wrap");
+
                        DOM.sinkEvents(columnSelector, Event.ONCLICK);
-                       
+
                        availableCells.put("0", new RowHeadersHeaderCell());
                }
-               
+
                public void updateCellFromUIDL(UIDL col) {
                        String cid = col.getStringAttribute("cid");
                        HeaderCell c = getHeaderCell(cid);
-                       if(c == null) {
-                               c = new HeaderCell(
-                                               cid,
-                                               col.getStringAttribute("caption")
-                                       );
+                       if (c == null) {
+                               c = new HeaderCell(cid, col.getStringAttribute("caption"));
                                availableCells.put(cid, c);
                        } else {
                                c.setText(col.getStringAttribute("caption"));
                        }
 
-                       if(col.hasAttribute("sortable")) {
+                       if (col.hasAttribute("sortable")) {
                                c.setSortable(true);
-                               if(cid.equals(sortColumn))
+                               if (cid.equals(sortColumn))
                                        c.setSorted(true);
                                else
                                        c.setSorted(false);
                        }
-                       if(col.hasAttribute("align")) {
+                       if (col.hasAttribute("align")) {
                                c.setAlign(col.getStringAttribute("align").charAt(0));
                        }
-                       if(col.hasAttribute("width")) {
-                               String width = col.getStringAttribute("width"); 
+                       if (col.hasAttribute("width")) {
+                               String width = col.getStringAttribute("width");
                                c.setWidth(Integer.parseInt(width));
                        }
                        // TODO icon
@@ -1078,7 +1134,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
                public void enableColumn(String cid, int index) {
                        HeaderCell c = getHeaderCell(cid);
-                       if(!c.isEnabled()) {
+                       if (!c.isEnabled()) {
                                setHeaderCell(index, c);
                        }
                }
@@ -1090,23 +1146,28 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                public void setHorizontalScrollPosition(int scrollLeft) {
                        DOM.setElementPropertyInt(hTableWrapper, "scrollLeft", scrollLeft);
                }
-               
+
                public void setWidth(int width) {
-                       DOM.setStyleAttribute(hTableWrapper, "width", (width - getColumnSelectorWidth()) + "px");
+                       DOM.setStyleAttribute(hTableWrapper, "width",
+                                       (width - getColumnSelectorWidth()) + "px");
                        super.setWidth(width + "px");
                }
-               
+
                public void setWidth(String width) {
-                       if(width.indexOf("px") > 0) {
-                               int w = Integer.parseInt(width.substring(0, width.indexOf("px")));
+                       if (width.indexOf("px") > 0) {
+                               int w = Integer.parseInt(width
+                                               .substring(0, width.indexOf("px")));
                                setWidth(w);
                        } else {
-                               // this is an IE6 hack, would need a generator to isolate from others
-                               if(isIE6()) {
+                               // this is an IE6 hack, would need a generator to isolate from
+                               // others
+                               if (Util.isIE6()) {
                                        DOM.setStyleAttribute(hTableWrapper, "width", (0) + "px");
                                        super.setWidth(width);
-                                       int hTableWrappersWidth = this.getOffsetWidth() - getColumnSelectorWidth();
-                                       DOM.setStyleAttribute(hTableWrapper, "width", hTableWrappersWidth + "px");
+                                       int hTableWrappersWidth = this.getOffsetWidth()
+                                                       - getColumnSelectorWidth();
+                                       DOM.setStyleAttribute(hTableWrapper, "width",
+                                                       hTableWrappersWidth + "px");
                                } else {
                                        super.setWidth(width);
                                }
@@ -1114,13 +1175,18 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                }
 
                private int getColumnSelectorWidth() {
-                       int w = DOM.getElementPropertyInt(columnSelector, "offsetWidth") + 4; // some extra to survive with IE6
+                       int w = DOM.getElementPropertyInt(columnSelector, "offsetWidth") + 4; // some
+                       // extra
+                       // to
+                       // survive
+                       // with
+                       // IE6
                        return w > 0 ? w : 15;
                }
 
                public void setColumnCollapsingAllowed(boolean cc) {
                        columnCollapsing = cc;
-                       if(cc) {
+                       if (cc) {
                                DOM.setStyleAttribute(columnSelector, "display", "block");
                        } else {
                                DOM.setStyleAttribute(columnSelector, "display", "none");
@@ -1128,46 +1194,48 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                }
 
                public void disableBrowserIntelligence() {
-                       DOM.setStyleAttribute(hTableContainer, "width", WRAPPER_WIDTH +"px");
+                       DOM.setStyleAttribute(hTableContainer, "width", WRAPPER_WIDTH
+                                       + "px");
                }
-               
+
                public void setHeaderCell(int index, HeaderCell cell) {
-                       if(index < visibleCells.size()) {
+                       if (index < visibleCells.size()) {
                                // insert to right slot
                                DOM.insertChild(tr, cell.getElement(), index);
                                adopt(cell);
                                visibleCells.insertElementAt(cell, index);
-                               
-                       } else ifindex == visibleCells.size()) {
-                               //simply append
+
+                       } else if (index == visibleCells.size()) {
+                               // simply append
                                DOM.appendChild(tr, cell.getElement());
                                adopt(cell);
                                visibleCells.add(cell);
                        } else {
-                               throw new RuntimeException("Header cells must be appended in order");
+                               throw new RuntimeException(
+                                               "Header cells must be appended in order");
                        }
                }
-               
+
                public HeaderCell getHeaderCell(int index) {
-                       if(index < visibleCells.size())
+                       if (index < visibleCells.size())
                                return (HeaderCell) visibleCells.get(index);
-                       else 
+                       else
                                return null;
                }
-               
+
                /**
                 * Get's HeaderCell by it's column Key.
                 * 
-                * Note that this returns HeaderCell even if it is currently
-                * collapsed.
+                * Note that this returns HeaderCell even if it is currently collapsed.
                 * 
-                * @param cid Column key of accessed HeaderCell
+                * @param cid
+                *            Column key of accessed HeaderCell
                 * @return HeaderCell
                 */
                public HeaderCell getHeaderCell(String cid) {
                        return (HeaderCell) availableCells.get(cid);
                }
-               
+
                public void moveCell(int oldIndex, int newIndex) {
                        HeaderCell hCell = getHeaderCell(oldIndex);
                        Element cell = hCell.getElement();
@@ -1178,13 +1246,13 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        DOM.insertChild(tr, cell, newIndex);
                        visibleCells.insertElementAt(hCell, newIndex);
                }
-               
+
                public Iterator iterator() {
                        return visibleCells.iterator();
                }
 
                public boolean remove(Widget w) {
-                       if(visibleCells.contains(w)) {
+                       if (visibleCells.contains(w)) {
                                visibleCells.remove(w);
                                orphan(w);
                                DOM.removeChild(DOM.getParent(w.getElement()), w.getElement());
@@ -1192,7 +1260,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        }
                        return false;
                }
-               
+
                public void removeCell(String colKey) {
                        HeaderCell c = getHeaderCell(colKey);
                        remove(c);
@@ -1200,46 +1268,45 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
                private void focusSlot(int index) {
                        removeSlotFocus();
-                       if(index > 0)
-                               DOM.setElementProperty(
-                                               DOM.getFirstChild(DOM.getChild(tr, index - 1)), 
-                                               "className", CLASSNAME+"-resizer "+CLASSNAME+"-focus-slot-right");
+                       if (index > 0)
+                               DOM.setElementProperty(DOM.getFirstChild(DOM.getChild(tr,
+                                               index - 1)), "className", CLASSNAME + "-resizer "
+                                               + CLASSNAME + "-focus-slot-right");
                        else
-                               DOM.setElementProperty(
-                                               DOM.getFirstChild(DOM.getChild(tr, index)), 
-                                               "className", CLASSNAME+"-resizer "+CLASSNAME+"-focus-slot-left");
+                               DOM.setElementProperty(DOM.getFirstChild(DOM
+                                               .getChild(tr, index)), "className", CLASSNAME
+                                               + "-resizer " + CLASSNAME + "-focus-slot-left");
                        focusedSlot = index;
                }
 
                private void removeSlotFocus() {
-                       if(focusedSlot < 0)
+                       if (focusedSlot < 0)
                                return;
-                       if(focusedSlot == 0)
-                               DOM.setElementProperty(
-                                               DOM.getFirstChild(DOM.getChild(tr, focusedSlot)), 
-                                               "className", CLASSNAME+"-resizer");
-                       else if( focusedSlot > 0)
-                               DOM.setElementProperty(
-                                               DOM.getFirstChild(DOM.getChild(tr, focusedSlot - 1)), 
-                                               "className", CLASSNAME+"-resizer");
+                       if (focusedSlot == 0)
+                               DOM.setElementProperty(DOM.getFirstChild(DOM.getChild(tr,
+                                               focusedSlot)), "className", CLASSNAME + "-resizer");
+                       else if (focusedSlot > 0)
+                               DOM.setElementProperty(DOM.getFirstChild(DOM.getChild(tr,
+                                               focusedSlot - 1)), "className", CLASSNAME + "-resizer");
                        focusedSlot = -1;
                }
-               
+
                public void onBrowserEvent(Event event) {
                        super.onBrowserEvent(event);
-                       if(DOM.compare(DOM.eventGetTarget(event), columnSelector)) {
+                       if (DOM.compare(DOM.eventGetTarget(event), columnSelector)) {
                                int left = DOM.getAbsoluteLeft(columnSelector);
-                               int top = DOM.getAbsoluteTop(columnSelector) +
-                                       DOM.getElementPropertyInt(columnSelector, "offsetHeight");
+                               int top = DOM.getAbsoluteTop(columnSelector)
+                                               + DOM.getElementPropertyInt(columnSelector,
+                                                               "offsetHeight");
                                client.getContextMenu().showAt(this, left, top);
                        }
                }
 
                class VisibleColumnAction extends IAction {
-                       
+
                        String colKey;
                        private boolean collapsed;
-                       
+
                        public VisibleColumnAction(String colKey) {
                                super(IScrollTable.TableHead.this);
                                this.colKey = colKey;
@@ -1249,15 +1316,15 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        public void execute() {
                                client.getContextMenu().hide();
                                // toggle selected column
-                               if(collapsedColumns.contains(colKey)) {
+                               if (collapsedColumns.contains(colKey)) {
                                        collapsedColumns.remove(colKey);
                                } else {
                                        tHead.removeCell(colKey);
                                        collapsedColumns.add(colKey);
                                }
-                               
-                               // update  variable to server
-                               client.updateVariable(paintableId, "collapsedcolumns", 
+
+                               // update variable to server
+                               client.updateVariable(paintableId, "collapsedcolumns",
                                                collapsedColumns.toArray(), false);
                                // let rowRequestHandler determine proper rows
                                rowRequestHandler.refreshContent();
@@ -1272,46 +1339,47 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                         */
                        public String getHTML() {
                                StringBuffer buf = new StringBuffer();
-                               if(collapsed)
+                               if (collapsed)
                                        buf.append("<span class=\"i-off\">");
                                buf.append(super.getHTML());
-                               if(collapsed)
+                               if (collapsed)
                                        buf.append("</span>");
                                return buf.toString();
                        }
-                       
-                       
+
                }
 
-               /* 
+               /*
                 * Returns columns as Action array for column select popup
                 */
                public IAction[] getActions() {
                        Object[] cols;
-                       if(IScrollTable.this.columnReordering) {
+                       if (IScrollTable.this.columnReordering) {
                                cols = columnOrder;
                        } else {
-                               // if columnReordering is disabled, we need different way to get all available columns
+                               // if columnReordering is disabled, we need different way to get
+                               // all available columns
                                cols = visibleColOrder;
-                               cols = new Object[visibleColOrder.length + collapsedColumns.size()];
+                               cols = new Object[visibleColOrder.length
+                                               + collapsedColumns.size()];
                                int i;
                                for (i = 0; i < visibleColOrder.length; i++) {
                                        cols[i] = visibleColOrder[i];
                                }
-                               for(Iterator it = collapsedColumns.iterator();it.hasNext();)
+                               for (Iterator it = collapsedColumns.iterator(); it.hasNext();)
                                        cols[i++] = it.next();
                        }
-                       IAction[] actions= new IAction[cols.length];
-                       
+                       IAction[] actions = new IAction[cols.length];
+
                        for (int i = 0; i < cols.length; i++) {
                                String cid = (String) cols[i];
                                HeaderCell c = getHeaderCell(cid);
                                VisibleColumnAction a = new VisibleColumnAction(c.getColKey());
                                a.setCaption(c.getCaption());
-                               if(!c.isEnabled())
+                               if (!c.isEnabled())
                                        a.setCollapsed(true);
                                actions[i] = a;
-                       }                       
+                       }
                        return actions;
                }
 
@@ -1330,42 +1398,42 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        Iterator it = visibleCells.iterator();
                        char[] aligns = new char[visibleCells.size()];
                        int colIndex = 0;
-                       while(it.hasNext()) {
+                       while (it.hasNext()) {
                                aligns[colIndex++] = ((HeaderCell) it.next()).getAlign();
                        }
                        return aligns;
                }
-               
+
        }
-       
+
        /**
-        * This Panel can only contain IScrollTableRow type of 
-        * widgets. This "simulates" very large table, keeping 
-        * spacers which take room of unrendered rows.
+        * This Panel can only contain IScrollTableRow type of widgets. This
+        * "simulates" very large table, keeping spacers which take room of
+        * unrendered rows.
         * 
         * @author mattitahvonen
-        *
+        * 
         */
        public class IScrollTableBody extends Panel {
 
                public static final int CELL_EXTRA_WIDTH = 20;
 
                public static final int DEFAULT_ROW_HEIGHT = 25;
-               
+
                private int rowHeight = -1;
-               
+
                private List renderedRows = new Vector();
-               
+
                private boolean initDone = false;
-               
+
                private int totalRows;
 
                Element preSpacer = DOM.createDiv();
                Element postSpacer = DOM.createDiv();
-               
+
                Element container = DOM.createDiv();
-               
-               Element tBody  = DOM.createTBody();
+
+               Element tBody = DOM.createTBody();
                Element table = DOM.createTable();
 
                private int firstRendered;
@@ -1378,85 +1446,91 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                        constructDOM();
                        setElement(container);
                }
-               
+
                private void constructDOM() {
-                       DOM.setElementProperty(table, "className", CLASSNAME+"-table");
-                       DOM.setElementProperty(preSpacer, "className", CLASSNAME+"-row-spacer");
-                       DOM.setElementProperty(postSpacer, "className", CLASSNAME+"-row-spacer");
+                       DOM.setElementProperty(table, "className", CLASSNAME + "-table");
+                       DOM.setElementProperty(preSpacer, "className", CLASSNAME
+                                       + "-row-spacer");
+                       DOM.setElementProperty(postSpacer, "className", CLASSNAME
+                                       + "-row-spacer");
 
                        DOM.appendChild(table, tBody);
                        DOM.appendChild(container, preSpacer);
                        DOM.appendChild(container, table);
                        DOM.appendChild(container, postSpacer);
-                       
+
                }
-               
+
                public int getAvailableWidth() {
                        return DOM.getElementPropertyInt(preSpacer, "offsetWidth");
                }
-               
-               public void renderInitialRows(UIDL rowData, int firstIndex, int rows, int totalRows) {
+
+               public void renderInitialRows(UIDL rowData, int firstIndex, int rows,
+                               int totalRows) {
                        this.totalRows = totalRows;
                        this.firstRendered = firstIndex;
-                       this.lastRendered = firstIndex + rows - 1 ;
+                       this.lastRendered = firstIndex + rows - 1;
                        Iterator it = rowData.getChildIterator();
                        aligns = tHead.getColumnAlignments();
-                       while(it.hasNext()) {
-                               IScrollTableRow row = new IScrollTableRow((UIDL) it.next(), aligns);
+                       while (it.hasNext()) {
+                               IScrollTableRow row = new IScrollTableRow((UIDL) it.next(),
+                                               aligns);
                                addRow(row);
                        }
-                       if(isAttached())
+                       if (isAttached())
                                fixSpacers();
                }
-               
+
                public void renderRows(UIDL rowData, int firstIndex, int rows) {
                        aligns = tHead.getColumnAlignments();
                        Iterator it = rowData.getChildIterator();
-                       if(firstIndex == lastRendered + 1) {
-                               while(it.hasNext()) {
+                       if (firstIndex == lastRendered + 1) {
+                               while (it.hasNext()) {
                                        IScrollTableRow row = createRow((UIDL) it.next());
                                        addRow(row);
                                        lastRendered++;
                                }
                                fixSpacers();
-                       } else if(firstIndex + rows == firstRendered) {
+                       } else if (firstIndex + rows == firstRendered) {
                                IScrollTableRow[] rowArray = new IScrollTableRow[rows];
                                int i = rows;
-                               while(it.hasNext()) {
+                               while (it.hasNext()) {
                                        i--;
                                        rowArray[i] = createRow((UIDL) it.next());
                                }
-                               for(i = 0 ; i < rows; i++) {
+                               for (i = 0; i < rows; i++) {
                                        addRowBeforeFirstRendered(rowArray[i]);
                                        firstRendered--;
                                }
-//                     } else if (firstIndex > lastRendered || firstIndex + rows < firstRendered) {
+                               // } else if (firstIndex > lastRendered || firstIndex + rows <
+                               // firstRendered) {
                        } else if (true) {
                                // completely new set of rows
                                // create one row before truncating row
                                IScrollTableRow row = createRow((UIDL) it.next());
-                               while(lastRendered + 1 > firstRendered)
+                               while (lastRendered + 1 > firstRendered)
                                        unlinkRow(false);
                                firstRendered = firstIndex;
-                               lastRendered = firstIndex - 1 ;
+                               lastRendered = firstIndex - 1;
                                fixSpacers();
                                addRow(row);
                                lastRendered++;
-                               while(it.hasNext()) {
+                               while (it.hasNext()) {
                                        addRow(createRow((UIDL) it.next()));
                                        lastRendered++;
                                }
                                fixSpacers();
                        } else {
                                // sorted or column reordering changed
-                               ApplicationConnection.getConsole().log("Bad update" + firstIndex + "/"+ rows);
+                               ApplicationConnection.getConsole().log(
+                                               "Bad update" + firstIndex + "/" + rows);
                        }
                }
-               
+
                /**
-                * This mehtod is used to instantiate new rows for this table.
-                * It automatically sets correct widths to rows cells and assigns 
-                * correct client reference for child widgets.
+                * This mehtod is used to instantiate new rows for this table. It
+                * automatically sets correct widths to rows cells and assigns correct
+                * client reference for child widgets.
                 * 
                 * This method can be called only after table has been initialized
                 * 
@@ -1465,53 +1539,56 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                private IScrollTableRow createRow(UIDL uidl) {
                        IScrollTableRow row = new IScrollTableRow(uidl, aligns);
                        int cells = DOM.getChildCount(row.getElement());
-                       for(int i = 0; i < cells; i++) {
+                       for (int i = 0; i < cells; i++) {
                                Element cell = DOM.getChild(row.getElement(), i);
                                int w = IScrollTable.this.getColWidth(getColKeyByIndex(i));
                                DOM.setStyleAttribute(cell, "width", w + "px");
-                               DOM.setStyleAttribute(DOM.getFirstChild(cell), "width", w + "px");
+                               DOM.setStyleAttribute(DOM.getFirstChild(cell), "width", w
+                                               + "px");
                        }
                        return row;
                }
 
                private void addRowBeforeFirstRendered(IScrollTableRow row) {
                        IScrollTableRow first = null;
-                       if(renderedRows.size()>0)
+                       if (renderedRows.size() > 0)
                                first = (IScrollTableRow) renderedRows.get(0);
-                       if(first != null && first.getStyleName().indexOf("i-odd") == -1)
+                       if (first != null && first.getStyleName().indexOf("i-odd") == -1)
                                row.addStyleName("i-odd");
                        DOM.insertChild(tBody, row.getElement(), 0);
                        adopt(row);
                        renderedRows.add(0, row);
                }
-               
+
                private void addRow(IScrollTableRow row) {
                        IScrollTableRow last = null;
-                       if(renderedRows.size()>0)
-                               last = (IScrollTableRow) renderedRows.get(renderedRows.size()-1);
-                       if(last != null && last.getStyleName().indexOf("i-odd") == -1)
+                       if (renderedRows.size() > 0)
+                               last = (IScrollTableRow) renderedRows
+                                               .get(renderedRows.size() - 1);
+                       if (last != null && last.getStyleName().indexOf("i-odd") == -1)
                                row.addStyleName("i-odd");
                        DOM.appendChild(tBody, row.getElement());
                        adopt(row);
                        renderedRows.add(row);
                }
-               
+
                public Iterator iterator() {
                        return renderedRows.iterator();
                }
-               
+
                public void unlinkRow(boolean fromBeginning) {
-                       if(lastRendered - firstRendered < 0)
+                       if (lastRendered - firstRendered < 0)
                                return;
                        int index;
-                       if(fromBeginning) {
+                       if (fromBeginning) {
                                index = 0;
                                firstRendered++;
                        } else {
                                index = renderedRows.size() - 1;
                                lastRendered--;
                        }
-                       IScrollTableRow toBeRemoved = (IScrollTableRow) renderedRows.get(index);
+                       IScrollTableRow toBeRemoved = (IScrollTableRow) renderedRows
+                                       .get(index);
                        DOM.removeChild(tBody, toBeRemoved.getElement());
                        this.orphan(toBeRemoved);
                        renderedRows.remove(index);
@@ -1521,29 +1598,34 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                public boolean remove(Widget w) {
                        throw new UnsupportedOperationException();
                }
-               
+
                protected void onAttach() {
                        super.onAttach();
                        fixSpacers();
                        // fix container blocks height to avoid "bouncing" when scrolling
-                       DOM.setStyleAttribute(container, "height", totalRows*getRowHeight() + "px");
+                       DOM.setStyleAttribute(container, "height", totalRows
+                                       * getRowHeight() + "px");
                }
-               
+
                private void fixSpacers() {
-                       DOM.setStyleAttribute(preSpacer, "height", getRowHeight()*firstRendered + "px");
-                       DOM.setStyleAttribute(postSpacer, "height", getRowHeight()*(totalRows - 1  - lastRendered) + "px");
+                       DOM.setStyleAttribute(preSpacer, "height", getRowHeight()
+                                       * firstRendered + "px");
+                       DOM.setStyleAttribute(postSpacer, "height", getRowHeight()
+                                       * (totalRows - 1 - lastRendered) + "px");
                }
 
                public int getTotalRows() {
                        return totalRows;
                }
-               
+
                public int getRowHeight() {
-                       if(initDone)
+                       if (initDone)
                                return rowHeight;
                        else {
-                               if(DOM.getChildCount(tBody) > 0) {
-                                       rowHeight = DOM.getElementPropertyInt(tBody, "offsetHeight")/DOM.getChildCount(tBody);
+                               if (DOM.getChildCount(tBody) > 0) {
+                                       rowHeight = DOM
+                                                       .getElementPropertyInt(tBody, "offsetHeight")
+                                                       / DOM.getChildCount(tBody);
                                } else {
                                        return DEFAULT_ROW_HEIGHT;
                                }
@@ -1553,7 +1635,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                }
 
                public int getColWidth(int i) {
-                       if(initDone) {
+                       if (initDone) {
                                Element e = DOM.getChild(DOM.getChild(tBody, 0), i);
                                return DOM.getElementPropertyInt(e, "offsetWidth");
                        } else {
@@ -1563,13 +1645,14 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
                public void setColWidth(int colIndex, int w) {
                        int rows = DOM.getChildCount(tBody);
-                       for(int i = 0; i < rows; i++) {
+                       for (int i = 0; i < rows; i++) {
                                Element cell = DOM.getChild(DOM.getChild(tBody, i), colIndex);
                                DOM.setStyleAttribute(cell, "width", w + "px");
-                               DOM.setStyleAttribute(DOM.getFirstChild(cell), "width", w + "px");
+                               DOM.setStyleAttribute(DOM.getFirstChild(cell), "width", w
+                                               + "px");
                        }
                }
-               
+
                public int getLastRendered() {
                        return lastRendered;
                }
@@ -1577,39 +1660,51 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                public int getFirstRendered() {
                        return firstRendered;
                }
-               
+
                public void moveCol(int oldIndex, int newIndex) {
-                       
+
                        // loop all rows and move given index to its new place
                        Iterator rows = iterator();
-                       while(rows.hasNext()) {
+                       while (rows.hasNext()) {
                                IScrollTableRow row = (IScrollTableRow) rows.next();
-                               
+
                                Element td = DOM.getChild(row.getElement(), oldIndex);
                                DOM.removeChild(row.getElement(), td);
 
                                DOM.insertChild(row.getElement(), td, newIndex);
-                               
+
                        }
 
                }
 
                public class IScrollTableRow extends Panel implements IActionOwner {
-                       
+
                        Vector childWidgets = new Vector();
                        private boolean selected = false;
                        private int rowKey;
-                       
+
                        private String[] actionKeys = null;
-                       
+
                        private IScrollTableRow(int rowKey) {
                                this.rowKey = rowKey;
                                setElement(DOM.createElement("tr"));
                                DOM.sinkEvents(getElement(), Event.ONCLICK);
                                attachContextMenuEvent(getElement());
-                               setStyleName(CLASSNAME+"-row");
+                               setStyleName(CLASSNAME + "-row");
+                       }
+
+                       protected void onDetach() {
+                               Util.removeContextMenuEvent(getElement());
+                               super.onDetach();
                        }
-                       
+
+                       /**
+                        * Attaches context menu event handler to given element. Attached
+                        * handler fires showContextMenu function.
+                        * 
+                        * @param el
+                        *            element where to attach contenxt menu event
+                        */
                        private native void attachContextMenuEvent(Element el) /*-{
                                var row = this;
                                el.oncontextmenu = function(e) {
@@ -1619,46 +1714,48 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                        return false;
                                };
                        }-*/;
-                       
+
                        public String getKey() {
                                return String.valueOf(rowKey);
                        }
 
                        public IScrollTableRow(UIDL uidl, char[] aligns) {
                                this(uidl.getIntAttribute("key"));
-                               
+
                                tHead.getColumnAlignments();
                                int col = 0;
                                // row header
-                               if(rowHeaders) {
+                               if (rowHeaders) {
                                        addCell(uidl.getStringAttribute("caption"), aligns[col++]);
                                }
-                               
-                               if(uidl.hasAttribute("al"))
+
+                               if (uidl.hasAttribute("al"))
                                        actionKeys = uidl.getStringArrayAttribute("al");
-                               
+
                                Iterator cells = uidl.getChildIterator();
-                               while(cells.hasNext()) {
+                               while (cells.hasNext()) {
                                        Object cell = cells.next();
                                        if (cell instanceof String) {
                                                addCell(cell.toString(), aligns[col++]);
                                        } else {
-                                               Widget cellContent = client.getWidget((UIDL) cell);
-                                               (( Paintable) cellContent).updateFromUIDL((UIDL) cell, client);
-                                               addCell(cellContent, aligns[col++]);
+                                               Widget cellContent = client.getWidget((UIDL) cell);
+                                               ((Paintable) cellContent).updateFromUIDL((UIDL) cell,
+                                                               client);
+                                               addCell(cellContent, aligns[col++]);
                                        }
                                }
-                               if(uidl.hasAttribute("selected") && !isSelected())
+                               if (uidl.hasAttribute("selected") && !isSelected())
                                        toggleSelection();
                        }
-                       
+
                        public void addCell(String text, char align) {
                                // String only content is optimized by not using Label widget
                                Element td = DOM.createTD();
                                Element container = DOM.createDiv();
-                               DOM.setElementProperty(container, "className", CLASSNAME+"-cell-content");
+                               DOM.setElementProperty(container, "className", CLASSNAME
+                                               + "-cell-content");
                                DOM.setInnerHTML(container, text);
-                               if(align != ALIGN_LEFT) {
+                               if (align != ALIGN_LEFT) {
                                        switch (align) {
                                        case ALIGN_CENTER:
                                                DOM.setStyleAttribute(container, "textAlign", "center");
@@ -1672,12 +1769,14 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                DOM.appendChild(td, container);
                                DOM.appendChild(getElement(), td);
                        }
-                       
+
                        public void addCell(Widget w, char align) {
                                Element td = DOM.createTD();
                                Element container = DOM.createDiv();
-                               DOM.setElementProperty(container, "className", CLASSNAME+"-cell-content");
-                               // TODO make widget cells respect align. text-align:center for IE, margin: auto for others
+                               DOM.setElementProperty(container, "className", CLASSNAME
+                                               + "-cell-content");
+                               // TODO make widget cells respect align. text-align:center for
+                               // IE, margin: auto for others
                                DOM.appendChild(td, container);
                                DOM.appendChild(getElement(), td);
                                DOM.appendChild(container, w.getElement());
@@ -1698,14 +1797,16 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                         * React on click that occur on content cells only
                         */
                        public void onBrowserEvent(Event event) {
-                               String s = DOM.getElementProperty(DOM.eventGetTarget(event), "className");
+                               String s = DOM.getElementProperty(DOM.eventGetTarget(event),
+                                               "className");
                                switch (DOM.eventGetType(event)) {
                                case Event.ONCLICK:
-                                       if((CLASSNAME+"-cell-content").equals(s)) {
+                                       if ((CLASSNAME + "-cell-content").equals(s)) {
                                                ApplicationConnection.getConsole().log("Row click");
-                                               if(selectMode > ITable.SELECT_MODE_NONE) {
+                                               if (selectMode > ITable.SELECT_MODE_NONE) {
                                                        toggleSelection();
-                                                       client.updateVariable(paintableId, "selected", selectedRowKeys.toArray(), immediate);
+                                                       client.updateVariable(paintableId, "selected",
+                                                                       selectedRowKeys.toArray(), immediate);
                                                }
                                        }
                                        break;
@@ -1715,10 +1816,10 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                }
                                super.onBrowserEvent(event);
                        }
-                       
+
                        public void showContextMenu(Event event) {
                                ApplicationConnection.getConsole().log("Context menu");
-                               if(actionKeys != null) {
+                               if (actionKeys != null) {
                                        int left = DOM.eventGetClientX(event);
                                        int top = DOM.eventGetClientY(event);
                                        top += Window.getScrollTop();
@@ -1733,8 +1834,8 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
 
                        private void toggleSelection() {
                                selected = !selected;
-                               if(selected) {
-                                       if(selectMode == ITable.SELECT_MODE_SINGLE)
+                               if (selected) {
+                                       if (selectMode == ITable.SELECT_MODE_SINGLE)
                                                IScrollTable.this.deselectAll();
                                        selectedRowKeys.add(String.valueOf(rowKey));
                                        addStyleName("i-selected");
@@ -1744,16 +1845,19 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                                }
                        }
 
-                       /* (non-Javadoc)
+                       /*
+                        * (non-Javadoc)
+                        * 
                         * @see com.itmill.toolkit.terminal.gwt.client.ui.IActionOwner#getActions()
                         */
                        public IAction[] getActions() {
-                               if(actionKeys == null)
+                               if (actionKeys == null)
                                        return new IAction[] {};
                                IAction[] actions = new IAction[actionKeys.length];
                                for (int i = 0; i < actions.length; i++) {
                                        String actionKey = actionKeys[i];
-                                       ITreeAction a = new ITreeAction(this, String.valueOf(rowKey), actionKey);
+                                       ITreeAction a = new ITreeAction(this, String
+                                                       .valueOf(rowKey), actionKey);
                                        a.setCaption(getActionCaption(actionKey));
                                        actions[i] = a;
                                }
@@ -1774,20 +1878,11 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll
                Object[] keys = selectedRowKeys.toArray();
                for (int i = 0; i < keys.length; i++) {
                        IScrollTableRow row = getRenderedRowByKey((String) keys[i]);
-                       if(row != null && row.isSelected())
+                       if (row != null && row.isSelected())
                                row.toggleSelection();
                }
                // still ensure all selects are removed from (not necessary rendered)
                selectedRowKeys.clear();
-               
-       }
 
-       public static native boolean isIE6() /*-{
-               var browser=$wnd.navigator.appName;
-               var version=parseFloat($wnd.navigator.appVersion);
-               if (browser=="Microsoft Internet Explorer" && (version < 7) ) {
-                       return true;
-               }
-               return false;
-       }-*/;
+       }
 }
index ab722443aa7e9d54e454e4d008fd719a20f06b93..d0ebfa59d272bd98b7bd5a5a569b9ecaa1ec9703 100644 (file)
@@ -15,6 +15,7 @@ import com.google.gwt.user.client.ui.TreeListener;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.Util;
 
 /**
  * TODO dump GWT's Tree implementation and use Toolkit 4 style
@@ -170,6 +171,11 @@ public class ITree extends Tree implements Paintable {
                        attachContextMenuEvent(getElement());
                }
                
+               public void remove() {
+                       Util.removeContextMenuEvent(getElement());
+                       super.remove();
+               }
+
                public void setSelected(boolean selected) {
                        if(!selected && !ITree.this.multiselect) {
                                this.setISelected(false);