]> source.dussan.org Git - vaadin-framework.git/commitdiff
Convert CellRenderer to revised EscalatorUpdater (#12645)
authorHenrik Paul <henrik@vaadin.com>
Wed, 13 Nov 2013 07:25:08 +0000 (09:25 +0200)
committerHenrik Paul <henrik@vaadin.com>
Wed, 13 Nov 2013 07:38:41 +0000 (09:38 +0200)
Change-Id: I046c53e775cdeaf4cfb02c47b3f2ca35231e4045

13 files changed:
client/src/com/vaadin/client/ui/grid/Cell.java
client/src/com/vaadin/client/ui/grid/CellRenderer.java [deleted file]
client/src/com/vaadin/client/ui/grid/Escalator.java
client/src/com/vaadin/client/ui/grid/EscalatorUpdater.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/FlyweightCell.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/FlyweightRow.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/Row.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/RowContainer.java
uitest/src/com/vaadin/tests/components/grid/BasicEscalator.html [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/BasicEscalator.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/GridTest.html [deleted file]
uitest/src/com/vaadin/tests/components/grid/GridTest.java [deleted file]
uitest/src/com/vaadin/tests/widgetset/client/grid/VTestGrid.java

index 08f3eeb9dcb56ff47bf7bf334f620e346b89733d..b06ad582b2dea8177603be3eddbc04be6c3150e5 100644 (file)
@@ -21,30 +21,29 @@ import com.google.gwt.user.client.Element;
 /**
  * A representation of a single cell.
  * <p>
- * A Cell instance will be provided to the {@link CellRenderer} responsible for
- * rendering the cells in a certain {@link RowContainer}.
+ * A Cell instance will be provided to the {@link EscalatorUpdater} responsible
+ * for rendering the cells in a certain {@link RowContainer}.
  * 
  * @since 7.2
  * @author Vaadin Ltd
- * @see CellRenderer#renderCell(Cell)
  */
 public interface Cell {
     /**
-     * Returns the index of the row this cell is in.
+     * Gets the index of the row this cell is in.
      * 
      * @return the index of the row this cell is in
      */
     public int getRow();
 
     /**
-     * Returns the index of the column this cell is in.
+     * Gets the index of the column this cell is in.
      * 
      * @return the index of the column this cell is in
      */
     public int getColumn();
 
     /**
-     * Returns the root element for this cell. The {@link CellRenderer} may
+     * Gets the root element for this cell. The {@link EscalatorUpdater} may
      * update the class names of the element, add inline styles and freely
      * modify the contents.
      * <p>
diff --git a/client/src/com/vaadin/client/ui/grid/CellRenderer.java b/client/src/com/vaadin/client/ui/grid/CellRenderer.java
deleted file mode 100644 (file)
index 636a512..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2000-2013 Vaadin Ltd.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.client.ui.grid;
-
-/**
- * An interface that defines how the cells in a {@link RowContainer} should look
- * like.
- * 
- * @since 7.2
- * @author Vaadin Ltd
- * @see RowContainer#setCellRenderer(CellRenderer)
- */
-public interface CellRenderer {
-    /** A {@link CellRenderer} that doesn't render anything. */
-    public static final CellRenderer NULL_RENDERER = new CellRenderer() {
-        @Override
-        public void renderCell(final Cell cell) {
-        }
-    };
-
-    /**
-     * Renders a cell contained in a row container.
-     * 
-     * @param cell
-     *            the cell that can be manipulated to modify the contents of the
-     *            cell being rendered. Never <code>null</code>.
-     */
-    public void renderCell(Cell cell);
-}
index d5311af3da3fddfe3ba7fd215998503f7650929c..f786ef304546d8ba8047dfdda33307925d9943af 100644 (file)
@@ -491,38 +491,10 @@ public class Escalator extends Widget {
         }
     }
 
-    private static class CellImpl implements Cell {
-        private final Element cellElem;
-        private final int row;
-        private final int column;
-
-        public CellImpl(final Element cellElem, final int row, final int column) {
-            this.cellElem = cellElem;
-            this.row = row;
-            this.column = column;
-        }
-
-        @Override
-        public int getRow() {
-            return row;
-        }
-
-        @Override
-        public int getColumn() {
-            return column;
-        }
-
-        @Override
-        public Element getElement() {
-            return cellElem;
-        }
-
-    }
-
     private static final String CLASS_NAME = "v-escalator";
 
     private abstract class AbstractRowContainer implements RowContainer {
-        private CellRenderer renderer = CellRenderer.NULL_RENDERER;
+        private EscalatorUpdater updater = EscalatorUpdater.NULL;
 
         private int rows;
 
@@ -555,17 +527,21 @@ public class Escalator extends Widget {
         }
 
         /**
-         * Returns a new element to be used as a cell in a row.
+         * Gets the tag name of an element to represent a cell in a row.
          * <p>
-         * Usually a {@code <th>} or {@code <td>}.
+         * Usually {@code "th"} or {@code "td"}.
+         * <p>
+         * <em>Note:</em> To actually <em>create</em> such an element, use
+         * {@link #createCellElement()} instead.
          * 
-         * @return a new element to be used as a cell in a row
+         * @return the tag name for the element to represent cells as
+         * @see #createCellElement()
          */
-        protected abstract Element createCellElement();
+        protected abstract String getCellElementTagName();
 
         @Override
-        public CellRenderer getCellRenderer() {
-            return renderer;
+        public EscalatorUpdater getEscalatorUpdater() {
+            return updater;
         }
 
         /**
@@ -578,13 +554,13 @@ public class Escalator extends Widget {
          * @see #hasColumnAndRowData()
          */
         @Override
-        public void setCellRenderer(final CellRenderer cellRenderer) {
-            if (cellRenderer == null) {
+        public void setEscalatorUpdater(final EscalatorUpdater escalatorUpdater) {
+            if (escalatorUpdater == null) {
                 throw new IllegalArgumentException(
-                        "cell renderer cannot be null");
+                        "escalator updater cannot be null");
             }
 
-            renderer = cellRenderer;
+            updater = escalatorUpdater;
 
             if (hasColumnAndRowData() && getRowCount() > 0) {
                 refreshRows(0, getRowCount());
@@ -713,9 +689,10 @@ public class Escalator extends Widget {
                 for (int col = 0; col < columnConfiguration.getColumnCount(); col++) {
                     final Element cellElem = createCellElement();
                     tr.appendChild(cellElem);
-                    paintCell(cellElem, row, col);
                 }
 
+                refreshRow(tr, row);
+
                 /*
                  * TODO [[optimize]] [[rowwidth]]: When this method is updated
                  * to measure things instead of using hardcoded values, it would
@@ -798,44 +775,27 @@ public class Escalator extends Widget {
         }
 
         void refreshRow(final Node tr, final int logicalRowIndex) {
+            flyweightRow.setup((Element) tr, logicalRowIndex);
+            updater.updateCells(flyweightRow, flyweightRow.getCells());
+
             /*
-             * TODO [[API]]: update this to use the row-based updater API in
-             * Artur's "design" project in github.
+             * the "assert" guarantees that this code is run only during
+             * development/debugging.
              */
-
-            for (int col = 0; col < tr.getChildCount(); col++) {
-                paintCell((Element) tr.getChild(col), logicalRowIndex, col);
-            }
+            assert flyweightRow.teardown();
         }
 
-        private void paintCell(final Element cellElem, final int row,
-                final int col) {
-            /*
-             * TODO [[optimize]]: Only do this for new cells or when a row
-             * height or column width actually changes. Or is it a NOOP when
-             * re-setting a property to its current value?
-             */
+        /**
+         * Create and setup an empty cell element.
+         * 
+         * @return a set-up empty cell element
+         */
+        public Element createCellElement() {
+            final Element cellElem = DOM.createElement(getCellElementTagName());
             cellElem.getStyle().setHeight(ROW_HEIGHT_PX, Unit.PX);
             cellElem.getStyle().setWidth(COLUMN_WIDTH_PX, Unit.PX);
-
-            /*
-             * TODO [[optimize]]: Don't create a new instance every time a cell
-             * is rendered
-             */
-            final CellImpl cell = new CellImpl(cellElem, row, col);
-            /*
-             * TODO [[optimize]] [[API]]: Let the renderer know whether the cell
-             * is new so that it can use a quicker route if it can deduct that
-             * the elements that it has put there in a previous rendering is
-             * still there and the contents only need to be updated.
-             */
-            renderer.renderCell(cell);
-
-            /*
-             * TODO [[optimize]]: Only do this for cells that have not already
-             * been rendered.
-             */
             cellElem.addClassName(CLASS_NAME + "-cell");
+            return cellElem;
         }
 
         /**
@@ -902,9 +862,10 @@ public class Escalator extends Widget {
                     final Element cellElem = createCellElement();
                     referenceCell = insertAfterReferenceAndUpdateIt(tr,
                             cellElem, referenceCell);
-                    paintCell(cellElem, topVisualRowLogicalIndex + row, col);
                 }
 
+                refreshRow(tr, topVisualRowLogicalIndex + row);
+
                 /*
                  * TODO [[optimize]] [[colwidth]]: When this method is updated
                  * to measure things instead of using hardcoded values, it would
@@ -972,8 +933,8 @@ public class Escalator extends Widget {
         }
 
         @Override
-        protected Element createCellElement() {
-            return DOM.createTH();
+        protected String getCellElementTagName() {
+            return "th";
         }
     }
 
@@ -983,8 +944,8 @@ public class Escalator extends Widget {
         }
 
         @Override
-        protected Element createCellElement() {
-            return DOM.createTD();
+        protected String getCellElementTagName() {
+            return "td";
         }
     }
 
@@ -1778,8 +1739,8 @@ public class Escalator extends Widget {
         }
 
         @Override
-        protected Element createCellElement() {
-            return DOM.createTD();
+        protected String getCellElementTagName() {
+            return "td";
         }
 
         private double calculateHeight() {
@@ -1849,6 +1810,7 @@ public class Escalator extends Widget {
         public void removeColumns(final int index, final int numberOfColumns) {
             assertArgumentsAreValidAndWithinRange(index, numberOfColumns);
 
+            flyweightRow.removeCells(index, numberOfColumns);
             columns -= numberOfColumns;
 
             if (hasSomethingInDom()) {
@@ -1898,6 +1860,7 @@ public class Escalator extends Widget {
                                 + numberOfColumns);
             }
 
+            flyweightRow.addCells(index, numberOfColumns);
             columns += numberOfColumns;
             if (hasColumnAndRowData()) {
                 for (final AbstractRowContainer rowContainer : rowContainers) {
@@ -1912,6 +1875,8 @@ public class Escalator extends Widget {
         }
     }
 
+    private FlyweightRow flyweightRow = new FlyweightRow(this);
+
     /** The {@code <thead/>} tag. */
     private final Element headElem = DOM.createTHead();
     /** The {@code <tbody/>} tag. */
@@ -2195,9 +2160,6 @@ public class Escalator extends Widget {
      * @throws IndexOutOfBoundsException
      *             if {@code columnIndex} is not a valid index for an existing
      *             column
-     * @throws IllegalArgumentException
-     *             if {@code columnIndex} indicates a column that is set to be
-     *             frozen
      */
     public void scrollToColumn(final int columnIndex,
             final ScrollDestination destination)
@@ -2227,9 +2189,6 @@ public class Escalator extends Widget {
      *             if {@code destination} is {@link ScrollDestination#MIDDLE},
      *             because having a padding on a centered column is undefined
      *             behavior
-     * @throws IllegalArgumentException
-     *             if {@code columnIndex} indicates a column that is set to be
-     *             frozen
      */
     public void scrollToColumn(final int columnIndex,
             final ScrollDestination destination, final int padding)
@@ -2290,7 +2249,7 @@ public class Escalator extends Widget {
      * @throws IllegalArgumentException
      *             if {@code destination} is {@link ScrollDestination#MIDDLE},
      *             because having a padding on a centered row is undefined
-     *             behavior.
+     *             behavior
      */
     public void scrollToRow(final int rowIndex,
             final ScrollDestination destination, final int padding)
diff --git a/client/src/com/vaadin/client/ui/grid/EscalatorUpdater.java b/client/src/com/vaadin/client/ui/grid/EscalatorUpdater.java
new file mode 100644 (file)
index 0000000..9a48dbf
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.client.ui.grid;
+
+import java.util.List;
+
+/**
+ * A functional interface that allows client code to define how a certain row in
+ * Escalator will be displayed. The contents of an escalator's header, body and
+ * footer are rendered by their respective updaters.
+ * <p>
+ * The updater is responsible for internally handling all remote communication,
+ * should the displayed data need to be fetched remotely.
+ * 
+ * @since 7.2
+ * @author Vaadin Ltd
+ * @see RowContainer#setEscalatorUpdater(EscalatorUpdater)
+ * @see Escalator#getHeader()
+ * @see Escalator#getBody()
+ * @see Escalator#getFooter()
+ */
+public interface EscalatorUpdater {
+    /** An {@link EscalatorUpdater} that doesn't render anything. */
+    public static final EscalatorUpdater NULL = new EscalatorUpdater() {
+        @Override
+        public void updateCells(final Row row, final List<Cell> cellsToUpdate) {
+            // NOOP
+        }
+    };
+
+    /**
+     * Renders a row contained in a row container.
+     * <p>
+     * <em>Note:</em> If rendering of cells is deferred (e.g. because
+     * asynchronous data retrieval), this method is responsible for explicitly
+     * displaying some placeholder data (empty content is valid). Because the
+     * cells (and rows) in an escalator are recycled, failing to reset a cell
+     * will lead to invalid data being displayed in the escalator.
+     * <p>
+     * For performance reasons, the escalator will never autonomously clear any
+     * data in a cell.
+     * 
+     * @param row
+     *            information about the row to update. <em>Note:</em> You should
+     *            not store nor reuse this reference
+     * @param cellsToUpdate
+     *            a collection of cells which need to be updated. <em>Note:</em>
+     *            You should neither store nor reuse the reference to the list,
+     *            nor to the individual cells
+     */
+    public void updateCells(Row row, List<Cell> cellsToUpdate);
+}
diff --git a/client/src/com/vaadin/client/ui/grid/FlyweightCell.java b/client/src/com/vaadin/client/ui/grid/FlyweightCell.java
new file mode 100644 (file)
index 0000000..88f05fa
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.ui.grid;
+
+import com.google.gwt.user.client.Element;
+
+/**
+ * An internal implementation of the {@link Cell} interface.
+ * <p>
+ * These instances are populated into a {@link FlyweightRow} instance, and
+ * intended to be reused when rendering cells in an escalator.
+ * 
+ * @since 7.2
+ * @author Vaadin Ltd
+ * @see FlyweightRow#getCells()
+ * @see FlyweightRow#addCells(int, int)
+ * @see FlyweightRow#removeCells(int, int)
+ */
+class FlyweightCell implements Cell {
+    private final int column;
+    private final FlyweightRow row;
+
+    public FlyweightCell(final FlyweightRow row, final int column) {
+        this.row = row;
+        this.column = column;
+    }
+
+    @Override
+    public int getRow() {
+        return row.getRow();
+    }
+
+    @Override
+    public int getColumn() {
+        return column;
+    }
+
+    @Override
+    public Element getElement() {
+        return (Element) row.getElement().getChild(column);
+    }
+
+}
diff --git a/client/src/com/vaadin/client/ui/grid/FlyweightRow.java b/client/src/com/vaadin/client/ui/grid/FlyweightRow.java
new file mode 100644 (file)
index 0000000..dae2758
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.ui.grid;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.user.client.Element;
+
+/**
+ * An internal implementation of the {@link Row} interface.
+ * <p>
+ * There is only one instance per Escalator. This is designed to be re-used when
+ * rendering rows.
+ * 
+ * @since 7.2
+ * @author Vaadin Ltd
+ * @see Escalator.AbstractRowContainer#refreshRow(Node, int)
+ */
+class FlyweightRow implements Row {
+    private static final int BLANK = Integer.MIN_VALUE;
+
+    private int row;
+    private Element element;
+    private final Escalator escalator;
+    private final List<Cell> cells = new ArrayList<Cell>();
+
+    public FlyweightRow(final Escalator escalator) {
+        this.escalator = escalator;
+    }
+
+    @Override
+    public Escalator getEscalator() {
+        return escalator;
+    }
+
+    void setup(final Element e, final int row) {
+        element = e;
+        this.row = row;
+    }
+
+    /**
+     * Tear down the state of the Row.
+     * <p>
+     * This is an internal check method, to prevent retrieving uninitialized
+     * data by calling {@link #getRow()}, {@link #getElement()} or
+     * {@link #getCells()} at an improper time.
+     * <p>
+     * This should only be used with asserts ("
+     * <code>assert flyweightRow.teardown()</code> ") so that the code is never
+     * run when asserts aren't enabled.
+     * 
+     * @return always <code>true</code>
+     */
+    boolean teardown() {
+        element = null;
+        row = BLANK;
+        return true;
+    }
+
+    @Override
+    public int getRow() {
+        assertSetup();
+        return row;
+    }
+
+    @Override
+    public Element getElement() {
+        assertSetup();
+        return element;
+    }
+
+    void addCells(final int index, final int numberOfColumns) {
+        for (int i = 0; i < numberOfColumns; i++) {
+            final int col = index + i;
+            cells.add(col, new FlyweightCell(this, col));
+        }
+        updateRestOfCells(index + numberOfColumns);
+    }
+
+    void removeCells(final int index, final int numberOfColumns) {
+        for (int i = 0; i < numberOfColumns; i++) {
+            cells.remove(index);
+        }
+        updateRestOfCells(index);
+    }
+
+    private void updateRestOfCells(final int startPos) {
+        // update the column number for the cells to the right
+        for (int col = startPos; col < cells.size(); col++) {
+            cells.set(col, new FlyweightCell(this, col));
+        }
+    }
+
+    /**
+     * Get flyweight cells for the client code to render.
+     * 
+     * @return a list of {@link FlyweightCell FlyweightCells}. They are
+     *         generified into {@link Cell Cells}, because Java's generics
+     *         system isn't expressive enough.
+     * @see #setup(Element, int)
+     * @see #teardown()
+     */
+    List<Cell> getCells() {
+        assertSetup();
+        return Collections.unmodifiableList(cells);
+    }
+
+    /**
+     * Asserts that the flyweight row has properly been set up before trying to
+     * access any of its data.
+     */
+    private void assertSetup() {
+        assert element != null && row != BLANK : "Flyweight row was not "
+                + "properly initialized. Make sure the setup-method is "
+                + "called before retrieving data. This is either a bug "
+                + "in Escalator, or the instance of the flyweight row "
+                + "has been stored and accessed.";
+    }
+}
diff --git a/client/src/com/vaadin/client/ui/grid/Row.java b/client/src/com/vaadin/client/ui/grid/Row.java
new file mode 100644 (file)
index 0000000..b6e2056
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.client.ui.grid;
+
+import com.google.gwt.user.client.Element;
+
+/**
+ * A representation of a row in an {@link Escalator}.
+ * 
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public interface Row {
+    /**
+     * Gets the escalator containing the row.
+     * 
+     * @return the escalator containing the row
+     */
+    public Escalator getEscalator();
+
+    /**
+     * Gets the row index.
+     * 
+     * @return the row index
+     */
+    public int getRow();
+
+    /**
+     * Gets the root element for this row.
+     * <p>
+     * The {@link EscalatorUpdater} may update the class names of the element
+     * and add inline styles, but may not modify the contained DOM structure.
+     * <p>
+     * If you wish to modify the cells within this row element, access them via
+     * the <code>List&lt;{@link Cell}&gt;</code> objects passed in to
+     * {@code EscalatorUpdater.updateCells(Row, List)}
+     * 
+     * @return the root element of the row
+     */
+    public Element getElement();
+}
\ No newline at end of file
index 5e826fe7432d8ec197a941fe7e9fdd9c0da8b1ef..6ef1c913b3e1084b92676a05d57e39fb834b0fc5 100644 (file)
@@ -28,24 +28,24 @@ package com.vaadin.client.ui.grid;
  */
 public interface RowContainer {
     /**
-     * Returns the current {@link CellRenderer} used to render cells.
+     * Returns the current {@link EscalatorUpdater} used to render cells.
      * 
-     * @return the current cell renderer
+     * @return the current escalator updater
      */
-    public CellRenderer getCellRenderer();
+    public EscalatorUpdater getEscalatorUpdater();
 
     /**
-     * Sets the {@link CellRenderer} to use when displaying data in the
+     * Sets the {@link EscalatorUpdater} to use when displaying data in the
      * escalator.
      * 
-     * @param cellRenderer
-     *            the cell renderer to use to render cells. May not be
+     * @param escalatorUpdater
+     *            the escalator updater to use to render cells. May not be
      *            <code>null</code>
      * @throws IllegalArgumentException
      *             if {@code cellRenderer} is <code>null</code>
-     * @see CellRenderer#NULL_RENDERER
+     * @see EscalatorUpdater#NULL
      */
-    public void setCellRenderer(CellRenderer cellRenderer)
+    public void setEscalatorUpdater(EscalatorUpdater escalatorUpdater)
             throws IllegalArgumentException;
 
     /**
@@ -74,7 +74,7 @@ public interface RowContainer {
      * downwards.
      * <p>
      * The contents of the inserted rows will subsequently be queried from the
-     * cell renderer.
+     * escalator updater.
      * <p>
      * <em>Note:</em> Only the contents of the inserted rows will be rendered.
      * If inserting new rows affects the contents of existing rows,
@@ -86,7 +86,7 @@ public interface RowContainer {
      *            {@link #getRowCount()} to add rows at the end
      * @param numberOfRows
      *            the number of rows to insert after the <code>index</code>
-     * @see #setCellRenderer(CellRenderer)
+     * @see #setEscalatorUpdater(EscalatorUpdater)
      * @throws IndexOutOfBoundsException
      *             if <code>index</code> is not an integer in the range
      *             <code>[0..{@link #getRowCount()}]</code>
@@ -106,7 +106,7 @@ public interface RowContainer {
      *            the index of the first row that will be updated
      * @param numberOfRows
      *            the number of rows to update, starting from the index
-     * @see #setCellRenderer(CellRenderer)
+     * @see #setEscalatorUpdater(EscalatorUpdater)
      * @throws IndexOutOfBoundsException
      *             if any integer number in the range
      *             <code>[index..(index+numberOfColumns)]</code> is not an
@@ -123,4 +123,4 @@ public interface RowContainer {
      * @return the number of rows in the current row container
      */
     public int getRowCount();
-}
\ No newline at end of file
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/BasicEscalator.html b/uitest/src/com/vaadin/tests/components/grid/BasicEscalator.html
new file mode 100644 (file)
index 0000000..70aa0fe
--- /dev/null
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>BasicEscalator</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">BasicEscalator</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.grid.BasicEscalator?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>Row 0: 0,0 (0)</td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[17]/domChild[9]</td>
+       <td>Cell: 9,17 (179)</td>
+</tr>
+<tr>
+       <td>verifyTextNotPresent</td>
+       <td>Cell: 0,100</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyTextNotPresent</td>
+       <td>Cell: 0,101</td>
+       <td></td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
+       <td>0</td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
+       <td>1</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[18]/domChild[0]</td>
+       <td>Row 0: 0,100 (190)</td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
+       <td>11</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[17]/domChild[0]</td>
+       <td>Row 11: 0,101 (200)</td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
+       <td>0</td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
+       <td>100</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[16]/domChild[0]</td>
+       <td>Row 0: 0,102 (210)</td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
+       <td>Row 16: 0,118 (370)</td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[0]</td>
+       <td>1109</td>
+</tr>
+<tr>
+       <td>verifyTextPresent</td>
+       <td>Row 56: 0,158</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyTextPresent</td>
+       <td>Row 72: 0,174</td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[0]</td>
+       <td>3690</td>
+</tr>
+<tr>
+       <td>verifyTextPresent</td>
+       <td>Row 201: 0,99</td>
+       <td></td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
+       <td>201</td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
+       <td>1</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
+       <td>Row 200: 0,98 (960)</td>
+</tr>
+<tr>
+       <td>verifyTextNotPresent</td>
+       <td>Row 201:</td>
+       <td></td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
+       <td>0</td>
+</tr>
+<tr>
+       <td>type</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
+       <td>2</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VHorizontalLayout[0]/Slot[2]/VButton[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[16]/domChild[0]</td>
+       <td>Row 184: 10,82 (974)</td>
+</tr>
+<tr>
+       <td>verifyText</td>
+       <td>vaadin=runcomvaadintestscomponentsgridBasicEscalator::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
+       <td>Row 200: 10,98 (1006)</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/grid/BasicEscalator.java b/uitest/src/com/vaadin/tests/components/grid/BasicEscalator.java
new file mode 100644 (file)
index 0000000..c8a35b7
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.components.grid;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.widgetset.TestingWidgetSet;
+import com.vaadin.tests.widgetset.server.grid.TestGrid;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.TextField;
+
+/**
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+@Widgetset(TestingWidgetSet.NAME)
+public class BasicEscalator extends AbstractTestUI {
+    public static final String ESCALATOR = "escalator";
+    public static final String INSERT_ROWS_OFFSET = "iro";
+    public static final String INSERT_ROWS_AMOUNT = "ira";
+    public static final String INSERT_ROWS_BUTTON = "irb";
+
+    @Override
+    protected void setup(final VaadinRequest request) {
+        final TestGrid grid = new TestGrid();
+        grid.setId(ESCALATOR);
+        addComponent(grid);
+
+        final Layout insertRowsLayout = new HorizontalLayout();
+        final TextField insertRowsOffset = new TextField();
+        insertRowsOffset.setId(INSERT_ROWS_OFFSET);
+        insertRowsLayout.addComponent(insertRowsOffset);
+        final TextField insertRowsAmount = new TextField();
+        insertRowsAmount.setId(INSERT_ROWS_AMOUNT);
+        insertRowsLayout.addComponent(insertRowsAmount);
+        insertRowsLayout.addComponent(new Button("insert rows",
+                new Button.ClickListener() {
+                    @Override
+                    @SuppressWarnings("boxing")
+                    public void buttonClick(final ClickEvent event) {
+                        final int offset = Integer.valueOf(insertRowsOffset
+                                .getValue());
+                        final int amount = Integer.valueOf(insertRowsAmount
+                                .getValue());
+                        grid.insertRows(offset, amount);
+                    }
+                }) {
+            {
+                setId(INSERT_ROWS_BUTTON);
+            }
+        });
+        addComponent(insertRowsLayout);
+
+        final Layout removeRowsLayout = new HorizontalLayout();
+        final TextField removeRowsOffset = new TextField();
+        removeRowsLayout.addComponent(removeRowsOffset);
+        final TextField removeRowsAmount = new TextField();
+        removeRowsLayout.addComponent(removeRowsAmount);
+        removeRowsLayout.addComponent(new Button("remove rows",
+                new Button.ClickListener() {
+                    @Override
+                    @SuppressWarnings("boxing")
+                    public void buttonClick(final ClickEvent event) {
+                        final int offset = Integer.valueOf(removeRowsOffset
+                                .getValue());
+                        final int amount = Integer.valueOf(removeRowsAmount
+                                .getValue());
+                        grid.removeRows(offset, amount);
+                    }
+                }));
+        addComponent(removeRowsLayout);
+
+        final Layout insertColumnsLayout = new HorizontalLayout();
+        final TextField insertColumnsOffset = new TextField();
+        insertColumnsLayout.addComponent(insertColumnsOffset);
+        final TextField insertColumnsAmount = new TextField();
+        insertColumnsLayout.addComponent(insertColumnsAmount);
+        insertColumnsLayout.addComponent(new Button("insert columns",
+                new Button.ClickListener() {
+                    @Override
+                    @SuppressWarnings("boxing")
+                    public void buttonClick(final ClickEvent event) {
+                        final int offset = Integer.valueOf(insertColumnsOffset
+                                .getValue());
+                        final int amount = Integer.valueOf(insertColumnsAmount
+                                .getValue());
+                        grid.insertColumns(offset, amount);
+                    }
+                }));
+        addComponent(insertColumnsLayout);
+
+        final Layout removeColumnsLayout = new HorizontalLayout();
+        final TextField removeColumnsOffset = new TextField();
+        removeColumnsLayout.addComponent(removeColumnsOffset);
+        final TextField removeColumnsAmount = new TextField();
+        removeColumnsLayout.addComponent(removeColumnsAmount);
+        removeColumnsLayout.addComponent(new Button("remove columns",
+                new Button.ClickListener() {
+                    @Override
+                    @SuppressWarnings("boxing")
+                    public void buttonClick(final ClickEvent event) {
+                        final int offset = Integer.valueOf(removeColumnsOffset
+                                .getValue());
+                        final int amount = Integer.valueOf(removeColumnsAmount
+                                .getValue());
+                        grid.removeColumns(offset, amount);
+                    }
+                }));
+        addComponent(removeColumnsLayout);
+
+        final HorizontalLayout rowScroll = new HorizontalLayout();
+        final NativeSelect destination = new NativeSelect();
+        destination.setNullSelectionAllowed(false);
+        destination.addItem("any");
+        destination.setValue("any");
+        destination.addItem("start");
+        destination.addItem("end");
+        destination.addItem("middle");
+        rowScroll.addComponent(destination);
+        final TextField rowIndex = new TextField();
+        rowScroll.addComponent(rowIndex);
+        final TextField rowPadding = new TextField();
+        rowScroll.addComponent(rowPadding);
+        rowScroll.addComponent(new Button("scroll to row",
+                new Button.ClickListener() {
+                    @Override
+                    public void buttonClick(final ClickEvent event) {
+                        int index;
+                        try {
+                            index = Integer.valueOf(rowIndex.getValue());
+                        } catch (NumberFormatException e) {
+                            index = 0;
+                        }
+
+                        int padding;
+                        try {
+                            padding = Integer.valueOf(rowPadding.getValue());
+                        } catch (NumberFormatException e) {
+                            padding = 0;
+                        }
+
+                        grid.scrollToRow(index,
+                                (String) destination.getValue(), padding);
+                    }
+                }));
+        addComponent(rowScroll);
+
+        final HorizontalLayout colScroll = new HorizontalLayout();
+        final NativeSelect colDestination = new NativeSelect();
+        colDestination.setNullSelectionAllowed(false);
+        colDestination.addItem("any");
+        colDestination.setValue("any");
+        colDestination.addItem("start");
+        colDestination.addItem("end");
+        colDestination.addItem("middle");
+        colScroll.addComponent(colDestination);
+        final TextField colIndex = new TextField();
+        colScroll.addComponent(colIndex);
+        final TextField colPadding = new TextField();
+        colScroll.addComponent(colPadding);
+        colScroll.addComponent(new Button("scroll to column",
+                new Button.ClickListener() {
+                    @Override
+                    public void buttonClick(final ClickEvent event) {
+                        int index;
+                        try {
+                            index = Integer.valueOf(colIndex.getValue());
+                        } catch (NumberFormatException e) {
+                            index = 0;
+                        }
+
+                        int padding;
+                        try {
+                            padding = Integer.valueOf(colPadding.getValue());
+                        } catch (NumberFormatException e) {
+                            padding = 0;
+                        }
+
+                        grid.scrollToColumn(index,
+                                (String) colDestination.getValue(), padding);
+                    }
+                }));
+        addComponent(colScroll);
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return null;
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return null;
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridTest.html b/uitest/src/com/vaadin/tests/components/grid/GridTest.html
deleted file mode 100644 (file)
index 33dda17..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>GridTest</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">GridTest</td></tr>
-</thead><tbody>
-<tr>
-       <td>open</td>
-       <td>/run/com.vaadin.tests.components.grid.GridTest?restartApplication</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
-       <td>Row 0: 0,0 (0)</td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[17]/domChild[9]</td>
-       <td>Cell: 9,17 (179)</td>
-</tr>
-<tr>
-       <td>verifyTextNotPresent</td>
-       <td>Cell: 0,100</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyTextNotPresent</td>
-       <td>Cell: 0,101</td>
-       <td></td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
-       <td>0</td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
-       <td>1</td>
-</tr>
-<tr>
-       <td>click</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[18]/domChild[0]</td>
-       <td>Row 0: 0,100 (190)</td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
-       <td>11</td>
-</tr>
-<tr>
-       <td>click</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[17]/domChild[0]</td>
-       <td>Row 11: 0,101 (200)</td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
-       <td>0</td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
-       <td>100</td>
-</tr>
-<tr>
-       <td>click</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[16]/domChild[0]</td>
-       <td>Row 0: 0,102 (210)</td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
-       <td>Row 16: 0,118 (370)</td>
-</tr>
-<tr>
-       <td>scroll</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[0]</td>
-       <td>1109</td>
-</tr>
-<tr>
-       <td>verifyTextPresent</td>
-       <td>Row 56: 0,158</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyTextPresent</td>
-       <td>Row 72: 0,174</td>
-       <td></td>
-</tr>
-<tr>
-       <td>scroll</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[0]</td>
-       <td>3690</td>
-</tr>
-<tr>
-       <td>verifyTextPresent</td>
-       <td>Row 201: 0,99</td>
-       <td></td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
-       <td>201</td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
-       <td>1</td>
-</tr>
-<tr>
-       <td>click</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VHorizontalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
-       <td>Row 200: 0,98 (960)</td>
-</tr>
-<tr>
-       <td>verifyTextNotPresent</td>
-       <td>Row 201:</td>
-       <td></td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VHorizontalLayout[0]/Slot[0]/VTextField[0]</td>
-       <td>0</td>
-</tr>
-<tr>
-       <td>type</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VHorizontalLayout[0]/Slot[1]/VTextField[0]</td>
-       <td>2</td>
-</tr>
-<tr>
-       <td>click</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VHorizontalLayout[0]/Slot[2]/VButton[0]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[16]/domChild[0]</td>
-       <td>Row 184: 10,82 (974)</td>
-</tr>
-<tr>
-       <td>verifyText</td>
-       <td>vaadin=runcomvaadintestscomponentsgridGridTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTestGrid[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
-       <td>Row 200: 10,98 (1006)</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridTest.java b/uitest/src/com/vaadin/tests/components/grid/GridTest.java
deleted file mode 100644 (file)
index 27b1d63..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2000-2013 Vaadin Ltd.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.tests.components.grid;
-
-import com.vaadin.annotations.Widgetset;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.tests.widgetset.TestingWidgetSet;
-import com.vaadin.tests.widgetset.server.grid.TestGrid;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.Layout;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.TextField;
-
-/**
- * @since 7.2
- * @author Vaadin Ltd
- */
-@Widgetset(TestingWidgetSet.NAME)
-public class GridTest extends AbstractTestUI {
-    @Override
-    protected void setup(final VaadinRequest request) {
-        final TestGrid grid = new TestGrid();
-        addComponent(grid);
-
-        final Layout insertRowsLayout = new HorizontalLayout();
-        final TextField insertRowsOffset = new TextField();
-        insertRowsLayout.addComponent(insertRowsOffset);
-        final TextField insertRowsAmount = new TextField();
-        insertRowsLayout.addComponent(insertRowsAmount);
-        insertRowsLayout.addComponent(new Button("insert rows",
-                new Button.ClickListener() {
-                    @Override
-                    @SuppressWarnings("boxing")
-                    public void buttonClick(final ClickEvent event) {
-                        final int offset = Integer.valueOf(insertRowsOffset
-                                .getValue());
-                        final int amount = Integer.valueOf(insertRowsAmount
-                                .getValue());
-                        grid.insertRows(offset, amount);
-                    }
-                }));
-        addComponent(insertRowsLayout);
-
-        final Layout removeRowsLayout = new HorizontalLayout();
-        final TextField removeRowsOffset = new TextField();
-        removeRowsLayout.addComponent(removeRowsOffset);
-        final TextField removeRowsAmount = new TextField();
-        removeRowsLayout.addComponent(removeRowsAmount);
-        removeRowsLayout.addComponent(new Button("remove rows",
-                new Button.ClickListener() {
-                    @Override
-                    @SuppressWarnings("boxing")
-                    public void buttonClick(final ClickEvent event) {
-                        final int offset = Integer.valueOf(removeRowsOffset
-                                .getValue());
-                        final int amount = Integer.valueOf(removeRowsAmount
-                                .getValue());
-                        grid.removeRows(offset, amount);
-                    }
-                }));
-        addComponent(removeRowsLayout);
-
-        final Layout insertColumnsLayout = new HorizontalLayout();
-        final TextField insertColumnsOffset = new TextField();
-        insertColumnsLayout.addComponent(insertColumnsOffset);
-        final TextField insertColumnsAmount = new TextField();
-        insertColumnsLayout.addComponent(insertColumnsAmount);
-        insertColumnsLayout.addComponent(new Button("insert columns",
-                new Button.ClickListener() {
-                    @Override
-                    @SuppressWarnings("boxing")
-                    public void buttonClick(final ClickEvent event) {
-                        final int offset = Integer.valueOf(insertColumnsOffset
-                                .getValue());
-                        final int amount = Integer.valueOf(insertColumnsAmount
-                                .getValue());
-                        grid.insertColumns(offset, amount);
-                    }
-                }));
-        addComponent(insertColumnsLayout);
-
-        final Layout removeColumnsLayout = new HorizontalLayout();
-        final TextField removeColumnsOffset = new TextField();
-        removeColumnsLayout.addComponent(removeColumnsOffset);
-        final TextField removeColumnsAmount = new TextField();
-        removeColumnsLayout.addComponent(removeColumnsAmount);
-        removeColumnsLayout.addComponent(new Button("remove columns",
-                new Button.ClickListener() {
-                    @Override
-                    @SuppressWarnings("boxing")
-                    public void buttonClick(final ClickEvent event) {
-                        final int offset = Integer.valueOf(removeColumnsOffset
-                                .getValue());
-                        final int amount = Integer.valueOf(removeColumnsAmount
-                                .getValue());
-                        grid.removeColumns(offset, amount);
-                    }
-                }));
-        addComponent(removeColumnsLayout);
-
-        final HorizontalLayout rowScroll = new HorizontalLayout();
-        final NativeSelect destination = new NativeSelect();
-        destination.setNullSelectionAllowed(false);
-        destination.addItem("any");
-        destination.setValue("any");
-        destination.addItem("start");
-        destination.addItem("end");
-        destination.addItem("middle");
-        rowScroll.addComponent(destination);
-        final TextField rowIndex = new TextField();
-        rowScroll.addComponent(rowIndex);
-        final TextField rowPadding = new TextField();
-        rowScroll.addComponent(rowPadding);
-        rowScroll.addComponent(new Button("scroll to row",
-                new Button.ClickListener() {
-                    @Override
-                    public void buttonClick(final ClickEvent event) {
-                        int index;
-                        try {
-                            index = Integer.valueOf(rowIndex.getValue());
-                        } catch (NumberFormatException e) {
-                            index = 0;
-                        }
-
-                        int padding;
-                        try {
-                            padding = Integer.valueOf(rowPadding.getValue());
-                        } catch (NumberFormatException e) {
-                            padding = 0;
-                        }
-
-                        grid.scrollToRow(index,
-                                (String) destination.getValue(), padding);
-                    }
-                }));
-        addComponent(rowScroll);
-
-        final HorizontalLayout colScroll = new HorizontalLayout();
-        final NativeSelect colDestination = new NativeSelect();
-        colDestination.setNullSelectionAllowed(false);
-        colDestination.addItem("any");
-        colDestination.setValue("any");
-        colDestination.addItem("start");
-        colDestination.addItem("end");
-        colDestination.addItem("middle");
-        colScroll.addComponent(colDestination);
-        final TextField colIndex = new TextField();
-        colScroll.addComponent(colIndex);
-        final TextField colPadding = new TextField();
-        colScroll.addComponent(colPadding);
-        colScroll.addComponent(new Button("scroll to column",
-                new Button.ClickListener() {
-                    @Override
-                    public void buttonClick(final ClickEvent event) {
-                        int index;
-                        try {
-                            index = Integer.valueOf(colIndex.getValue());
-                        } catch (NumberFormatException e) {
-                            index = 0;
-                        }
-
-                        int padding;
-                        try {
-                            padding = Integer.valueOf(colPadding.getValue());
-                        } catch (NumberFormatException e) {
-                            padding = 0;
-                        }
-
-                        grid.scrollToColumn(index,
-                                (String) colDestination.getValue(), padding);
-                    }
-                }));
-        addComponent(colScroll);
-    }
-
-    @Override
-    protected String getTestDescription() {
-        return null;
-    }
-
-    @Override
-    protected Integer getTicketNumber() {
-        return null;
-    }
-
-}
index 154b1d2bc9d821b017aa8fa7b965b7f9960f6e56..5edc2ab0a08dba856ac3c39cffebe18e1f1e8edb 100644 (file)
@@ -5,9 +5,10 @@ import java.util.List;
 
 import com.google.gwt.user.client.ui.Composite;
 import com.vaadin.client.ui.grid.Cell;
-import com.vaadin.client.ui.grid.CellRenderer;
 import com.vaadin.client.ui.grid.ColumnConfiguration;
 import com.vaadin.client.ui.grid.Escalator;
+import com.vaadin.client.ui.grid.EscalatorUpdater;
+import com.vaadin.client.ui.grid.Row;
 import com.vaadin.client.ui.grid.RowContainer;
 import com.vaadin.client.ui.grid.ScrollDestination;
 
@@ -19,52 +20,61 @@ public class VTestGrid extends Composite {
         private final List<Integer> columns = new ArrayList<Integer>();
         private final List<Integer> rows = new ArrayList<Integer>();
 
-        public void insertRows(int offset, int amount) {
-            List<Integer> newRows = new ArrayList<Integer>();
+        @SuppressWarnings("boxing")
+        public void insertRows(final int offset, final int amount) {
+            final List<Integer> newRows = new ArrayList<Integer>();
             for (int i = 0; i < amount; i++) {
                 newRows.add(rowCounter++);
             }
             rows.addAll(offset, newRows);
         }
 
-        public void insertColumns(int offset, int amount) {
-            List<Integer> newColumns = new ArrayList<Integer>();
+        @SuppressWarnings("boxing")
+        public void insertColumns(final int offset, final int amount) {
+            final List<Integer> newColumns = new ArrayList<Integer>();
             for (int i = 0; i < amount; i++) {
                 newColumns.add(columnCounter++);
             }
             columns.addAll(offset, newColumns);
         }
 
-        public CellRenderer createHeaderRenderer() {
-            return new CellRenderer() {
+        public EscalatorUpdater createHeaderUpdater() {
+            return new EscalatorUpdater() {
                 @Override
-                public void renderCell(Cell cell) {
-                    int columnName = columns.get(cell.getColumn());
-                    cell.getElement().setInnerText("Header " + columnName);
+                public void updateCells(final Row row,
+                        final List<Cell> cellsToUpdate) {
+                    for (final Cell cell : cellsToUpdate) {
+                        final Integer columnName = columns
+                                .get(cell.getColumn());
+                        cell.getElement().setInnerText("Header " + columnName);
+                    }
                 }
             };
         }
 
-        public CellRenderer createFooterRenderer() {
-            return new CellRenderer() {
+        public EscalatorUpdater createFooterUpdater() {
+            return new EscalatorUpdater() {
                 @Override
-                public void renderCell(Cell cell) {
-                    int columnName = columns.get(cell.getColumn());
-                    cell.getElement().setInnerText("Footer " + columnName);
+                public void updateCells(final Row row,
+                        final List<Cell> cellsToUpdate) {
+                    for (final Cell cell : cellsToUpdate) {
+                        final Integer columnName = columns
+                                .get(cell.getColumn());
+                        cell.getElement().setInnerText("Footer " + columnName);
+                    }
                 }
             };
         }
 
-        public CellRenderer createBodyRenderer() {
-            return new CellRenderer() {
-                int i = 0;
+        public EscalatorUpdater createBodyUpdater() {
+            return new EscalatorUpdater() {
+                private int i = 0;
 
-                @Override
-                public void renderCell(Cell cell) {
-                    int columnName = columns.get(cell.getColumn());
-                    int rowName = rows.get(cell.getRow());
-                    String cellInfo = columnName + "," + rowName + " (" + i
-                            + ")";
+                public void renderCell(final Cell cell) {
+                    final Integer columnName = columns.get(cell.getColumn());
+                    final Integer rowName = rows.get(cell.getRow());
+                    final String cellInfo = columnName + "," + rowName + " ("
+                            + i + ")";
 
                     if (cell.getColumn() > 0) {
                         cell.getElement().setInnerText("Cell: " + cellInfo);
@@ -73,10 +83,10 @@ public class VTestGrid extends Composite {
                                 "Row " + cell.getRow() + ": " + cellInfo);
                     }
 
-                    double c = i * .1;
-                    int r = (int) ((Math.cos(c) + 1) * 128);
-                    int g = (int) ((Math.cos(c / Math.PI) + 1) * 128);
-                    int b = (int) ((Math.cos(c / (Math.PI * 2)) + 1) * 128);
+                    final double c = i * .1;
+                    final int r = (int) ((Math.cos(c) + 1) * 128);
+                    final int g = (int) ((Math.cos(c / Math.PI) + 1) * 128);
+                    final int b = (int) ((Math.cos(c / (Math.PI * 2)) + 1) * 128);
                     cell.getElement()
                             .getStyle()
                             .setBackgroundColor(
@@ -89,36 +99,44 @@ public class VTestGrid extends Composite {
 
                     i++;
                 }
+
+                @Override
+                public void updateCells(final Row row,
+                        final List<Cell> cellsToUpdate) {
+                    for (final Cell cell : cellsToUpdate) {
+                        renderCell(cell);
+                    }
+                }
             };
         }
 
-        public void removeRows(int offset, int amount) {
+        public void removeRows(final int offset, final int amount) {
             for (int i = 0; i < amount; i++) {
                 rows.remove(offset);
             }
         }
 
-        public void removeColumns(int offset, int amount) {
+        public void removeColumns(final int offset, final int amount) {
             for (int i = 0; i < amount; i++) {
                 columns.remove(offset);
             }
         }
     }
 
-    private Escalator escalator = new Escalator();
-    private Data data = new Data();
+    private final Escalator escalator = new Escalator();
+    private final Data data = new Data();
 
     public VTestGrid() {
         initWidget(escalator);
-        RowContainer header = escalator.getHeader();
-        header.setCellRenderer(data.createHeaderRenderer());
+        final RowContainer header = escalator.getHeader();
+        header.setEscalatorUpdater(data.createHeaderUpdater());
         header.insertRows(0, 1);
 
-        RowContainer footer = escalator.getFooter();
-        footer.setCellRenderer(data.createFooterRenderer());
+        final RowContainer footer = escalator.getFooter();
+        footer.setEscalatorUpdater(data.createFooterUpdater());
         footer.insertRows(0, 1);
 
-        escalator.getBody().setCellRenderer(data.createBodyRenderer());
+        escalator.getBody().setEscalatorUpdater(data.createBodyUpdater());
 
         insertRows(0, 100);
         insertColumns(0, 10);
@@ -128,12 +146,12 @@ public class VTestGrid extends Composite {
 
     }
 
-    public void insertRows(int offset, int number) {
+    public void insertRows(final int offset, final int number) {
         data.insertRows(offset, number);
         escalator.getBody().insertRows(offset, number);
     }
 
-    public void insertColumns(int offset, int number) {
+    public void insertColumns(final int offset, final int number) {
         data.insertColumns(offset, number);
         escalator.getColumnConfiguration().insertColumns(offset, number);
     }
@@ -142,8 +160,8 @@ public class VTestGrid extends Composite {
         return escalator.getColumnConfiguration();
     }
 
-    public void scrollToRow(int index, ScrollDestination destination,
-            int padding) {
+    public void scrollToRow(final int index,
+            final ScrollDestination destination, final int padding) {
         if (padding != 0) {
             escalator.scrollToRow(index, destination, padding);
         } else {
@@ -151,8 +169,8 @@ public class VTestGrid extends Composite {
         }
     }
 
-    public void scrollToColumn(int index, ScrollDestination destination,
-            int padding) {
+    public void scrollToColumn(final int index,
+            final ScrollDestination destination, final int padding) {
         if (padding != 0) {
             escalator.scrollToColumn(index, destination, padding);
         } else {
@@ -160,12 +178,12 @@ public class VTestGrid extends Composite {
         }
     }
 
-    public void removeRows(int offset, int amount) {
+    public void removeRows(final int offset, final int amount) {
         data.removeRows(offset, amount);
         escalator.getBody().removeRows(offset, amount);
     }
 
-    public void removeColumns(int offset, int amount) {
+    public void removeColumns(final int offset, final int amount) {
         data.removeColumns(offset, amount);
         escalator.getColumnConfiguration().removeColumns(offset, amount);
     }