]> source.dussan.org Git - vaadin-framework.git/commitdiff
Implement Grid client-side Sorting API (#13334)
authorPatrik Lindström <patrik@vaadin.com>
Tue, 17 Jun 2014 15:30:04 +0000 (18:30 +0300)
committerPatrik Lindström <patrik@vaadin.com>
Thu, 26 Jun 2014 13:15:05 +0000 (16:15 +0300)
Change-Id: I9ab18c93bdc1aaf66aa2701c3939311671a60f04

12 files changed:
client/src/com/vaadin/client/ui/grid/Grid.java
client/src/com/vaadin/client/ui/grid/datasources/ListDataSource.java
client/src/com/vaadin/client/ui/grid/sort/Sort.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/sort/SortEvent.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/sort/SortEventHandler.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/sort/SortOrder.java [new file with mode: 0644]
client/tests/src/com/vaadin/client/ui/grid/ListDataSourceTest.java
shared/src/com/vaadin/shared/ui/grid/SortDirection.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java
uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java
uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererRpc.java
uitest/src/com/vaadin/tests/widgetset/server/grid/GridClientColumnRenderers.java

index dfcda40b045373a65ff201dcc3d1fe7be9df28dd..1739e286083e0afb4a275f8ad71b84fbe99c67f0 100644 (file)
@@ -49,16 +49,21 @@ import com.vaadin.client.ui.grid.selection.SelectionModel;
 import com.vaadin.client.ui.grid.selection.SelectionModelMulti;
 import com.vaadin.client.ui.grid.selection.SelectionModelNone;
 import com.vaadin.client.ui.grid.selection.SelectionModelSingle;
+import com.vaadin.client.ui.grid.sort.Sort;
+import com.vaadin.client.ui.grid.sort.SortEvent;
+import com.vaadin.client.ui.grid.sort.SortEventHandler;
+import com.vaadin.client.ui.grid.sort.SortOrder;
 import com.vaadin.shared.ui.grid.GridConstants;
 import com.vaadin.shared.ui.grid.HeightMode;
 import com.vaadin.shared.ui.grid.Range;
 import com.vaadin.shared.ui.grid.ScrollDestination;
+import com.vaadin.shared.ui.grid.SortDirection;
 import com.vaadin.shared.util.SharedUtil;
 
 /**
  * A data grid view that supports columns and lazy loading of data rows from a
  * data source.
- * 
+ *
  * <h3>Columns</h3>
  * <p>
  * The {@link GridColumn} class defines the renderer used to render a cell in
@@ -72,15 +77,15 @@ import com.vaadin.shared.util.SharedUtil;
  * specific column index using {@link Grid#getColumn(int)}.
  * </p>
  * <p>
- * 
+ *
  * TODO Explain about headers/footers once the multiple header/footer api has
  * been implemented
- * 
+ *
  * <h3>Data sources</h3>
  * <p>
  * TODO Explain about what a data source is and how it should be implemented.
  * </p>
- * 
+ *
  * @param <T>
  *            The row type of the grid. The row type is the POJO type from where
  *            the data is retrieved into the column cells.
@@ -213,6 +218,12 @@ public class Grid<T> extends Composite implements
      */
     private GridColumn<?, T> lastFrozenColumn;
 
+    /**
+     * Current sort order. The (private) sort() method reads this list to
+     * determine the order in which to present rows.
+     */
+    private List<SortOrder> sortOrder = new ArrayList<SortOrder>();
+
     private Renderer<Boolean> selectColumnRenderer = null;
 
     private SelectionColumn selectionColumn;
@@ -269,10 +280,10 @@ public class Grid<T> extends Composite implements
     /**
      * Base class for grid columns internally used by the Grid. The user should
      * use {@link GridColumn} when creating new columns.
-     * 
+     *
      * @param <C>
      *            the column type
-     * 
+     *
      * @param <T>
      *            the row type
      */
@@ -320,7 +331,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Constructs a new column with a custom renderer.
-         * 
+         *
          * @param renderer
          *            The renderer to use for rendering the cells
          */
@@ -334,7 +345,7 @@ public class Grid<T> extends Composite implements
         /**
          * Constructs a new column with custom renderers for rows, header and
          * footer cells.
-         * 
+         *
          * @param bodyRenderer
          *            The renderer to use for rendering body cells
          * @param headerRenderer
@@ -355,7 +366,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Internally used by the grid to set itself
-         * 
+         *
          * @param grid
          */
         private void setGrid(Grid<T> grid) {
@@ -371,7 +382,7 @@ public class Grid<T> extends Composite implements
         /**
          * Gets text in the header of the column. By default the header caption
          * is empty.
-         * 
+         *
          * @return the text displayed in the column caption
          */
         public String getHeaderCaption() {
@@ -380,7 +391,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Returns the renderer used for rendering the header cells
-         * 
+         *
          * @return a renderer that renders header cells
          */
         public Renderer<String> getHeaderRenderer() {
@@ -389,7 +400,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Sets the renderer that renders header cells. Should not be null.
-         * 
+         *
          * @param renderer
          *            The renderer to use for rendering header cells.
          */
@@ -405,7 +416,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Returns the renderer used for rendering the footer cells
-         * 
+         *
          * @return a renderer that renders footer cells
          */
         public Renderer<String> getFooterRenderer() {
@@ -414,7 +425,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Sets the renderer that renders footer cells. Should not be null.
-         * 
+         *
          * @param renderer
          *            The renderer to use for rendering footer cells.
          */
@@ -430,7 +441,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Sets the text in the header of the column.
-         * 
+         *
          * @param caption
          *            the text displayed in the column header
          */
@@ -449,7 +460,7 @@ public class Grid<T> extends Composite implements
         /**
          * Gets text in the footer of the column. By default the footer caption
          * is empty.
-         * 
+         *
          * @return The text displayed in the footer of the column
          */
         public String getFooterCaption() {
@@ -458,7 +469,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Sets text in the footer of the column.
-         * 
+         *
          * @param caption
          *            the text displayed in the footer of the column
          */
@@ -476,7 +487,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Is the column visible. By default all columns are visible.
-         * 
+         *
          * @return <code>true</code> if the column is visible
          */
         @Override
@@ -486,7 +497,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Sets a column as visible in the grid.
-         * 
+         *
          * @param visible
          *            <code>true</code> if the column should be displayed in the
          *            grid
@@ -515,19 +526,26 @@ public class Grid<T> extends Composite implements
         }
 
         /**
-         * Returns the data that should be rendered into the cell.
-         * 
+         * Returns the data that should be rendered into the cell. By default
+         * returning Strings and Widgets are supported. If the return type is a
+         * String then it will be treated as preformatted text.
+         * <p>
+         * To support other types you will need to pass a custom renderer to the
+         * column via the column constructor.
+         *
          * @param row
          *            The row object that provides the cell content.
-         * 
+         *
          * @return The cell content
          */
         public abstract C getValue(T row);
 
         /**
-         * Returns the renderer used to render the cells of this column.
-         * 
-         * @return the renderer to render the cell content with
+         * The renderer to render the cell width. By default renders the data as
+         * a String or adds the widget into the cell if the column type is of
+         * widget type.
+         *
+         * @return The renderer to render the cell content with
          */
         public Renderer<? super C> getRenderer() {
             return bodyRenderer;
@@ -535,7 +553,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Finds the index of this column instance
-         * 
+         *
          */
         private int findIndexOfColumn() {
             return grid.findVisibleColumnIndex((GridColumn<?, T>) this);
@@ -544,7 +562,7 @@ public class Grid<T> extends Composite implements
         /**
          * Sets the pixel width of the column. Use a negative value for the grid
          * to autosize column based on content and available space
-         * 
+         *
          * @param pixels
          *            the width in pixels or negative for auto sizing
          */
@@ -561,7 +579,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Returns the pixel width of the column
-         * 
+         *
          * @return pixel width of the column
          */
         public int getWidth() {
@@ -594,7 +612,7 @@ public class Grid<T> extends Composite implements
 
         /**
          * Constructs an updater for updating a header / footer
-         * 
+         *
          * @param rows
          *            The row container
          * @param inverted
@@ -607,17 +625,17 @@ public class Grid<T> extends Composite implements
 
         /**
          * Gets the header/footer caption value
-         * 
+         *
          * @param column
          *            The column to get the value for.
-         * 
+         *
          * @return The value that should be rendered for the column caption
          */
         public abstract String getColumnValue(GridColumn<?, T> column);
 
         /**
          * Gets the group caption value
-         * 
+         *
          * @param group
          *            The group for with the caption value should be returned
          * @return The value that should be rendered for the column caption
@@ -626,34 +644,34 @@ public class Grid<T> extends Composite implements
 
         /**
          * Is the row visible in the header/footer
-         * 
+         *
          * @param row
          *            the row to check
-         * 
+         *
          * @return <code>true</code> if the row should be visible
          */
         public abstract boolean isRowVisible(ColumnGroupRow<T> row);
 
         /**
          * Should the first row be visible
-         * 
+         *
          * @return <code>true</code> if the first row should be visible
          */
         public abstract boolean firstRowIsVisible();
 
         /**
          * The renderer that renders the cell
-         * 
+         *
          * @param column
          *            The column for which the cell should be rendered
-         * 
+         *
          * @return renderer used for rendering
          */
         public abstract Renderer<String> getRenderer(GridColumn<?, T> column);
 
         /**
          * The renderer that renders the cell for column groups
-         * 
+         *
          * @param group
          *            The group that should be rendered
          * @return renderer used for rendering
@@ -780,7 +798,7 @@ public class Grid<T> extends Composite implements
     /**
      * Creates the header updater that updates the escalator header rows from
      * the column and column group rows.
-     * 
+     *
      * @return the updater that updates the data in the escalator.
      */
     private EscalatorUpdater createHeaderUpdater() {
@@ -950,7 +968,7 @@ public class Grid<T> extends Composite implements
     /**
      * Creates the footer updater that updates the escalator footer rows from
      * the column and column group rows.
-     * 
+     *
      * @return the updater that updates the data in the escalator.
      */
     private EscalatorUpdater createFooterUpdater() {
@@ -990,7 +1008,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Refreshes header or footer rows on demand
-     * 
+     *
      * @param rows
      *            The row container
      * @param firstRowIsVisible
@@ -1042,7 +1060,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Adds a column as the last column in the grid.
-     * 
+     *
      * @param column
      *            the column to add
      */
@@ -1052,7 +1070,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Inserts a column into a specific position in the grid.
-     * 
+     *
      * @param index
      *            the index where the column should be inserted into
      * @param column
@@ -1161,7 +1179,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Removes a column from the grid.
-     * 
+     *
      * @param column
      *            the column to remove
      */
@@ -1196,7 +1214,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Returns the amount of columns in the grid.
-     * 
+     *
      * @return The number of columns in the grid
      */
     public int getColumnCount() {
@@ -1205,7 +1223,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Returns a list of columns in the grid.
-     * 
+     *
      * @return A unmodifiable list of the columns in the grid
      */
     public List<GridColumn<?, T>> getColumns() {
@@ -1215,7 +1233,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Returns a column by its index in the grid.
-     * 
+     *
      * @param index
      *            the index of the column
      * @return The column in the given index
@@ -1232,30 +1250,30 @@ public class Grid<T> extends Composite implements
 
     /**
      * Set the column headers visible.
-     * 
+     *
      * <p>
      * A column header is a single cell header on top of each column reserved
      * for a specific header for that column. The column header can be set by
      * {@link GridColumn#setHeaderCaption(String)} and column headers cannot be
      * merged with other column headers.
      * </p>
-     * 
+     *
      * <p>
      * All column headers occupy the first header row of the grid. If you do not
      * wish to show the column headers in the grid you should hide the row by
      * setting visibility of the header row to <code>false</code>.
      * </p>
-     * 
+     *
      * <p>
      * If you want to merge the column headers into groups you can use
      * {@link ColumnGroupRow}s to group columns together and give them a common
      * header. See {@link #addColumnGroupRow()} for details.
      * </p>
-     * 
+     *
      * <p>
      * The header row is by default visible.
      * </p>
-     * 
+     *
      * @param visible
      *            <code>true</code> if header rows should be visible
      */
@@ -1269,7 +1287,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Are the column headers visible
-     * 
+     *
      * @return <code>true</code> if they are visible
      */
     public boolean isColumnHeadersVisible() {
@@ -1278,30 +1296,30 @@ public class Grid<T> extends Composite implements
 
     /**
      * Set the column footers visible.
-     * 
+     *
      * <p>
      * A column footer is a single cell footer below of each column reserved for
      * a specific footer for that column. The column footer can be set by
      * {@link GridColumn#setFooterCaption(String)} and column footers cannot be
      * merged with other column footers.
      * </p>
-     * 
+     *
      * <p>
      * All column footers occupy the first footer row of the grid. If you do not
      * wish to show the column footers in the grid you should hide the row by
      * setting visibility of the footer row to <code>false</code>.
      * </p>
-     * 
+     *
      * <p>
      * If you want to merge the column footers into groups you can use
      * {@link ColumnGroupRow}s to group columns together and give them a common
      * footer. See {@link #addColumnGroupRow()} for details.
      * </p>
-     * 
+     *
      * <p>
      * The footer row is by default hidden.
      * </p>
-     * 
+     *
      * @param visible
      *            <code>true</code> if the footer row should be visible
      */
@@ -1315,9 +1333,9 @@ public class Grid<T> extends Composite implements
 
     /**
      * Are the column footers visible
-     * 
+     *
      * @return <code>true</code> if they are visible
-     * 
+     *
      */
     public boolean isColumnFootersVisible() {
         return columnFootersVisible;
@@ -1325,15 +1343,15 @@ public class Grid<T> extends Composite implements
 
     /**
      * Adds a new column group row to the grid.
-     * 
+     *
      * <p>
      * Column group rows are rendered in the header and footer of the grid.
      * Column group rows are made up of column groups which groups together
      * columns for adding a common auxiliary header or footer for the columns.
      * </p>
-     * 
+     *
      * Example usage:
-     * 
+     *
      * <pre>
      * // Add a new column group row to the grid
      * ColumnGroupRow row = grid.addColumnGroupRow();
@@ -1347,7 +1365,7 @@ public class Grid<T> extends Composite implements
      * // Set a common footer for &quot;Column1&quot; and &quot;Column2&quot;
      * column12.setFooter(&quot;Column 1&amp;2&quot;);
      * </pre>
-     * 
+     *
      * @return a column group row instance you can use to add column groups
      */
     public ColumnGroupRow<T> addColumnGroupRow() {
@@ -1360,10 +1378,10 @@ public class Grid<T> extends Composite implements
 
     /**
      * Adds a new column group row to the grid at a specific index.
-     * 
+     *
      * @see #addColumnGroupRow() {@link Grid#addColumnGroupRow()} for example
      *      usage
-     * 
+     *
      * @param rowIndex
      *            the index where the column group row should be added
      * @return a column group row instance you can use to add column groups
@@ -1378,7 +1396,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Removes a column group row
-     * 
+     *
      * @param row
      *            The row to remove
      */
@@ -1390,9 +1408,9 @@ public class Grid<T> extends Composite implements
 
     /**
      * Get the column group rows
-     * 
+     *
      * @return a unmodifiable list of column group rows
-     * 
+     *
      */
     public List<ColumnGroupRow<T>> getColumnGroupRows() {
         return Collections.unmodifiableList(new ArrayList<ColumnGroupRow<T>>(
@@ -1401,7 +1419,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Returns the column group for a row and column
-     * 
+     *
      * @param row
      *            The row of the column
      * @param column
@@ -1425,7 +1443,7 @@ public class Grid<T> extends Composite implements
      * <p>
      * <em>Note:</em> This method will change the widget's size in the browser
      * only if {@link #getHeightMode()} returns {@link HeightMode#CSS}.
-     * 
+     *
      * @see #setHeightMode(HeightMode)
      */
     @Override
@@ -1440,7 +1458,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Sets the data source used by this grid.
-     * 
+     *
      * @param dataSource
      *            the data source to use, not null
      * @throws IllegalArgumentException
@@ -1493,7 +1511,7 @@ public class Grid<T> extends Composite implements
      * <p>
      * All columns up to and including the given column will be frozen in place
      * when the grid is scrolled sideways.
-     * 
+     *
      * @param lastFrozenColumn
      *            the rightmost column to freeze, or <code>null</code> to not
      *            have any columns frozen
@@ -1526,7 +1544,7 @@ public class Grid<T> extends Composite implements
      * <em>Note:</em> Most usually, this method returns the very value set with
      * {@link #setLastFrozenColumn(GridColumn)}. This value, however, can be
      * reset to <code>null</code> if the column is removed from this grid.
-     * 
+     *
      * @return the rightmost frozen column in the grid, or <code>null</code> if
      *         no columns are frozen.
      */
@@ -1546,7 +1564,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Scrolls to a certain row, using {@link ScrollDestination#ANY}.
-     * 
+     *
      * @param rowIndex
      *            zero-based index of the row to scroll to.
      * @throws IllegalArgumentException
@@ -1560,7 +1578,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Scrolls to a certain row, using user-specified scroll destination.
-     * 
+     *
      * @param rowIndex
      *            zero-based index of the row to scroll to.
      * @param destination
@@ -1579,7 +1597,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Scrolls to a certain row using only user-specified parameters.
-     * 
+     *
      * @param rowIndex
      *            zero-based index of the row to scroll to.
      * @param destination
@@ -1636,7 +1654,7 @@ public class Grid<T> extends Composite implements
      * <p>
      * If Grid is currently not in {@link HeightMode#ROW}, the given value is
      * remembered, and applied once the mode is applied.
-     * 
+     *
      * @param rows
      *            The height in terms of number of rows displayed in Grid's
      *            body. If Grid doesn't contain enough rows, white space is
@@ -1648,7 +1666,7 @@ public class Grid<T> extends Composite implements
      *             infinite}
      * @throws IllegalArgumentException
      *             if {@code rows} is {@link Double#isNaN(double) NaN}
-     * 
+     *
      * @see #setHeightMode(HeightMode)
      */
     public void setHeightByRows(double rows) throws IllegalArgumentException {
@@ -1660,7 +1678,7 @@ public class Grid<T> extends Composite implements
      * {@link #getHeightMode()} is {@link HeightMode#ROW}.
      * <p>
      * By default, it is {@value Escalator#DEFAULT_HEIGHT_BY_ROWS}.
-     * 
+     *
      * @return the amount of rows that should be shown in Grid's body, while in
      *         {@link HeightMode#ROW}.
      * @see #setHeightByRows(double)
@@ -1680,7 +1698,7 @@ public class Grid<T> extends Composite implements
      * <em>Note:</em> If headers/footers are inserted or removed, the widget
      * will resize itself to still display the required amount of rows in its
      * body. It also takes the horizontal scrollbar into account.
-     * 
+     *
      * @param heightMode
      *            the mode in to which Grid should be set
      */
@@ -1702,7 +1720,7 @@ public class Grid<T> extends Composite implements
      * Returns the current {@link HeightMode} the Grid is in.
      * <p>
      * Defaults to {@link HeightMode#CSS}.
-     * 
+     *
      * @return the current HeightMode
      */
     public HeightMode getHeightMode() {
@@ -1865,7 +1883,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Accesses the package private method Widget#setParent()
-     * 
+     *
      * @param widget
      *            The widget to access
      * @param parent
@@ -1878,7 +1896,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Sets the current selection model.
-     * 
+     *
      * @param selectionModel
      *            a selection model implementation.
      * @throws IllegalArgumentException
@@ -1896,7 +1914,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Gets a reference to the current selection model.
-     * 
+     *
      * @return the currently used SelectionModel instance.
      */
     public SelectionModel<T> getSelectionModel() {
@@ -1907,7 +1925,7 @@ public class Grid<T> extends Composite implements
      * Sets current selection mode.
      * <p>
      * This is a shorthand method for {@link Grid#setSelectionModel}.
-     * 
+     *
      * @param mode
      *            a selection mode value
      * @see {@link SelectionMode}.
@@ -1919,7 +1937,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Test if a row is selected.
-     * 
+     *
      * @param row
      *            a row object
      * @return true, if the current selection model considers the provided row
@@ -1935,7 +1953,7 @@ public class Grid<T> extends Composite implements
      * Only selection models implementing {@link SelectionModel.Single} and
      * {@link SelectionModel.Multi} are supported; for anything else, an
      * exception will be thrown.
-     * 
+     *
      * @param row
      *            a row object
      * @return <code>true</code> iff the current selection changed
@@ -1960,7 +1978,7 @@ public class Grid<T> extends Composite implements
      * Only selection models implementing {@link SelectionModel.Single} and
      * {@link SelectionModel.Multi} are supported; for anything else, an
      * exception will be thrown.
-     * 
+     *
      * @param row
      *            a row object
      * @return <code>true</code> iff the current selection changed
@@ -1985,7 +2003,7 @@ public class Grid<T> extends Composite implements
      * Only selection models implementing {@link SelectionModel.Single} are
      * valid for this method; for anything else, use the
      * {@link Grid#getSelectedRows()} method.
-     * 
+     *
      * @return a selected row reference, or null, if no row is selected
      * @throws IllegalStateException
      *             if the current selection model is not an instance of
@@ -2002,7 +2020,7 @@ public class Grid<T> extends Composite implements
 
     /**
      * Gets currently selected rows from the current selection model.
-     * 
+     *
      * @return a non-null collection containing all currently selected rows.
      */
     public Collection<T> getSelectedRows() {
@@ -2015,4 +2033,91 @@ public class Grid<T> extends Composite implements
         return addHandler(handler, SelectionChangeEvent.getType());
     }
 
+    /**
+     * Sets the current sort order using the fluid Sort API. Read the
+     * documentation for {@link Sort} for more information.
+     *
+     * @param s
+     *            a sort instance
+     */
+    public void sort(Sort s) {
+        setSortOrder(s.build());
+    }
+
+    /**
+     * Sorts the Grid data in ascending order along one column.
+     *
+     * @param column
+     *            a grid column reference
+     */
+    public <C> void sort(GridColumn<C, T> column) {
+        sort(column, SortDirection.ASCENDING);
+    }
+
+    /**
+     * Sorts the Grid data along one column.
+     *
+     * @param column
+     *            a grid column reference
+     * @param direction
+     *            a sort direction value
+     */
+    public <C> void sort(GridColumn<C, T> column, SortDirection direction) {
+        sort(Sort.by(column, direction));
+    }
+
+    /**
+     * Sets the sort order to use. Setting this causes the Grid to re-sort
+     * itself.
+     *
+     * @param order
+     *            a sort order list. If set to null, the sort order is cleared.
+     */
+    public void setSortOrder(List<SortOrder> order) {
+        sortOrder.clear();
+        if (order != null) {
+            sortOrder.addAll(order);
+        }
+        sort();
+    }
+
+    /**
+     * Get a copy of the current sort order array.
+     *
+     * @return a copy of the current sort order array
+     */
+    public List<SortOrder> getSortOrder() {
+        return Collections.unmodifiableList(sortOrder);
+    }
+
+    /**
+     * Register a GWT event handler for a sorting event. This handler gets
+     * called whenever this Grid needs its data source to provide data sorted in
+     * a specific order.
+     *
+     * @param handler
+     *            a sort event handler
+     * @return the registration for the event
+     */
+    public HandlerRegistration addSortHandler(SortEventHandler<T> handler) {
+        return addHandler(handler, SortEvent.getType());
+    }
+
+    /**
+     * Apply sorting to data source.
+     */
+    private void sort() {
+        fireEvent(new SortEvent<T>(this,
+                Collections.unmodifiableList(sortOrder)));
+    }
+
+    /**
+     * Missing getDataSource method. TODO: remove this and other duplicates
+     * after The Merge
+     *
+     * @return a DataSource reference
+     */
+    public DataSource<T> getDataSource() {
+        return dataSource;
+    }
 }
index 94c32bfb338d7256422de515eb9e23547e86ccc2..97b358a29956eadbfc029168eb0252422aad52d3 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2000-2014 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
@@ -18,6 +18,8 @@ package com.vaadin.client.ui.grid.datasources;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
@@ -30,23 +32,23 @@ import com.vaadin.shared.util.SharedUtil;
  * A simple list based on an in-memory data source for simply adding a list of
  * row pojos to the grid. Based on a wrapped list instance which supports adding
  * and removing of items.
- * 
+ *
  * <p>
  * Usage:
- * 
+ *
  * <pre>
  * ListDataSource&lt;Integer&gt; ds = new ListDataSource&lt;Integer&gt;(1, 2, 3, 4);
- * 
+ *
  * // Add item to the data source
  * ds.asList().add(5);
- * 
+ *
  * // Remove item from the data source
  * ds.asList().remove(3);
- * 
+ *
  * // Add multiple items
  * ds.asList().addAll(Arrays.asList(5, 6, 7));
  * </pre>
- * 
+ *
  * @since 7.4
  * @author Vaadin Ltd
  */
@@ -342,8 +344,8 @@ public class ListDataSource<T> implements DataSource<T> {
      * data source after the data source has been constructed. To add or remove
      * items to the data source after it has been constructed use
      * {@link ListDataSource#asList()}.
-     * 
-     * 
+     *
+     *
      * @param datasource
      *            The list to use for providing the data to the grid
      */
@@ -359,7 +361,7 @@ public class ListDataSource<T> implements DataSource<T> {
      * Constructs a data source with a set of rows. You can dynamically add and
      * remove rows from the data source via the list you get from
      * {@link ListDataSource#asList()}
-     * 
+     *
      * @param rows
      *            The rows to initially add to the data source
      */
@@ -401,7 +403,7 @@ public class ListDataSource<T> implements DataSource<T> {
      * <p>
      * Note: The list is not the same list as passed into the data source via
      * the constructor.
-     * 
+     *
      * @return Returns a list implementation that wraps the real list that backs
      *         the data source and provides events for the data source
      *         listeners.
@@ -416,4 +418,18 @@ public class ListDataSource<T> implements DataSource<T> {
                 + row;
         return new RowHandleImpl(row);
     }
+
+    /**
+     * Sort entire container according to a {@link Comparator}.
+     *
+     * @param comparator
+     *            a comparator object, which compares two data source entries
+     *            (beans/pojos)
+     */
+    public void sort(Comparator<T> comparator) {
+        Collections.sort(ds, comparator);
+        if (changeHandler != null) {
+            changeHandler.dataUpdated(0, ds.size());
+        }
+    }
 }
diff --git a/client/src/com/vaadin/client/ui/grid/sort/Sort.java b/client/src/com/vaadin/client/ui/grid/sort/Sort.java
new file mode 100644 (file)
index 0000000..fdf3c64
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2000-2014 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.sort;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.client.ui.grid.GridColumn;
+import com.vaadin.shared.ui.grid.SortDirection;
+
+/**
+ * Fluid Sort descriptor object.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ * @param T
+ *            grid data type
+ */
+public class Sort {
+
+    private final Sort previous;
+    private final SortOrder order;
+    private final int count;
+
+    /**
+     * Basic constructor, used by the {@link #by(GridColumn)} and
+     * {@link #by(GridColumn, SortDirection)} methods.
+     *
+     * @param column
+     *            a grid column
+     * @param direction
+     *            a sort direction
+     */
+    private Sort(GridColumn<?, ?> column, SortDirection direction) {
+        previous = null;
+        count = 1;
+        order = new SortOrder(column, direction);
+    }
+
+    /**
+     * Extension constructor. Performs object equality checks on all previous
+     * Sort objects in the chain to make sure that the column being passed in
+     * isn't already used earlier (which would indicate a bug). If the column
+     * has been used before, this constructor throws an
+     * {@link IllegalStateException}.
+     *
+     * @param previous
+     *            the sort instance that the new sort instance is to extend
+     * @param column
+     *            a (previously unused) grid column reference
+     * @param direction
+     *            a sort direction
+     */
+    private Sort(Sort previous, GridColumn<?, ?> column, SortDirection direction) {
+        this.previous = previous;
+        count = previous.count + 1;
+        order = new SortOrder(column, direction);
+
+        Sort s = previous;
+        while (s != null) {
+            if (s.order.getColumn() == column) {
+                throw new IllegalStateException(
+                        "Can not sort along the same column twice");
+            }
+            s = s.previous;
+        }
+    }
+
+    /**
+     * Start building a Sort order by sorting a provided column in ascending
+     * order.
+     *
+     * @param column
+     *            a grid column object reference
+     * @return a sort instance, typed to the grid data type
+     */
+    public static Sort by(GridColumn<?, ?> column) {
+        return by(column, SortDirection.ASCENDING);
+    }
+
+    /**
+     * Start building a Sort order by sorting a provided column.
+     *
+     * @param column
+     *            a grid column object reference
+     * @param direction
+     *            indicator of sort direction - either ascending or descending
+     * @return a sort instance, typed to the grid data type
+     */
+    public static Sort by(GridColumn<?, ?> column, SortDirection direction) {
+        return new Sort(column, direction);
+    }
+
+    /**
+     * Continue building a Sort order. The provided column is sorted in
+     * ascending order if the previously added columns have been evaluated as
+     * equals.
+     *
+     * @param column
+     *            a grid column object reference
+     * @return a sort instance, typed to the grid data type
+     */
+    public Sort then(GridColumn<?, ?> column) {
+        return then(column, SortDirection.ASCENDING);
+    }
+
+    /**
+     * Continue building a Sort order. The provided column is sorted in
+     * specified order if the previously added columns have been evaluated as
+     * equals.
+     *
+     * @param column
+     *            a grid column object reference
+     * @param direction
+     *            indicator of sort direction - either ascending or descending
+     * @return a sort instance, typed to the grid data type
+     */
+    public Sort then(GridColumn<?, ?> column, SortDirection direction) {
+        return new Sort(this, column, direction);
+    }
+
+    /**
+     * Build a sort order list. This method is called internally by Grid when
+     * calling {@link com.vaadin.client.ui.grid.Grid#sort(Sort)}, but can also
+     * be called manually to create a SortOrder list, which can also be provided
+     * directly to Grid.
+     *
+     * @return a sort order list.
+     */
+    public List<SortOrder> build() {
+
+        List<SortOrder> order = new ArrayList<SortOrder>(count);
+
+        Sort s = this;
+        for (int i = count - 1; i >= 0; --i) {
+            order.add(0, s.order);
+            s = s.previous;
+        }
+
+        return order;
+    }
+}
diff --git a/client/src/com/vaadin/client/ui/grid/sort/SortEvent.java b/client/src/com/vaadin/client/ui/grid/sort/SortEvent.java
new file mode 100644 (file)
index 0000000..d39cdfc
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2014 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.sort;
+
+import java.util.List;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.vaadin.client.data.DataSource;
+import com.vaadin.client.ui.grid.Grid;
+
+/**
+ * A sort event, fired by the Grid when it needs its data source to provide data
+ * sorted in a specific manner.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class SortEvent<T> extends GwtEvent<SortEventHandler<?>> {
+
+    private static final Type<SortEventHandler<?>> TYPE = new Type<SortEventHandler<?>>();
+
+    private final Grid<T> grid;
+    private final List<SortOrder> order;
+
+    /**
+     * Creates a new Sort Event. All provided parameters are final, and passed
+     * on as-is.
+     *
+     * @param grid
+     *            a grid reference
+     * @param datasource
+     *            a reference to the grid's data source
+     * @param order
+     *            an array dictating the desired sort order of the data source
+     */
+    public SortEvent(Grid<T> grid, List<SortOrder> order) {
+        this.grid = grid;
+        this.order = order;
+    }
+
+    @Override
+    public Type<SortEventHandler<?>> getAssociatedType() {
+        return TYPE;
+    }
+
+    /**
+     * Static access to the GWT event type identifier associated with this Event
+     * class
+     *
+     * @return a type object, uniquely describing this event type.
+     */
+    public static Type<SortEventHandler<?>> getType() {
+        return TYPE;
+    }
+
+    /**
+     * Get access to the Grid that fired this event
+     *
+     * @return the grid instance
+     */
+    @Override
+    public Grid<T> getSource() {
+        return grid;
+    }
+
+    /**
+     * Get access to the Grid that fired this event
+     *
+     * @return the grid instance
+     */
+    public Grid<T> getGrid() {
+        return grid;
+    }
+
+    /**
+     * Access the data source of the Grid that fired this event
+     *
+     * @return a data source instance
+     */
+    public DataSource<T> getDataSource() {
+        return grid.getDataSource();
+    }
+
+    /**
+     * Get the sort ordering that is to be applied to the Grid
+     *
+     * @return a list of sort order objects
+     */
+    public List<SortOrder> getOrder() {
+        return order;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void dispatch(SortEventHandler<?> handler) {
+        ((SortEventHandler<T>) handler).sort(this);
+    }
+
+}
diff --git a/client/src/com/vaadin/client/ui/grid/sort/SortEventHandler.java b/client/src/com/vaadin/client/ui/grid/sort/SortEventHandler.java
new file mode 100644 (file)
index 0000000..8895b43
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 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.sort;
+
+import com.google.gwt.event.shared.EventHandler;
+
+/**
+ * Handler for a Grid sort event, called when the Grid needs its data source to
+ * provide data sorted in a specific manner.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public interface SortEventHandler<T> extends EventHandler {
+
+    /**
+     * Handle sorting of the Grid. This method is called when a re-sorting of
+     * the Grid's data is requested.
+     *
+     * @param event
+     *            the sort event
+     */
+    public void sort(SortEvent<T> event);
+
+}
diff --git a/client/src/com/vaadin/client/ui/grid/sort/SortOrder.java b/client/src/com/vaadin/client/ui/grid/sort/SortOrder.java
new file mode 100644 (file)
index 0000000..bd76124
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2014 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.sort;
+
+import com.vaadin.client.ui.grid.GridColumn;
+import com.vaadin.shared.ui.grid.SortDirection;
+
+/**
+ * Sort order descriptor. Contains column and direction references.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ * @param T
+ *            grid data type
+ */
+public class SortOrder {
+
+    private final GridColumn<?, ?> column;
+    private final SortDirection direction;
+
+    /**
+     * Create a sort order descriptor.
+     *
+     * @param column
+     *            a grid column descriptor object
+     * @param direction
+     *            a sorting direction value (ascending or descending)
+     */
+    public SortOrder(GridColumn<?, ?> column, SortDirection direction) {
+        if (column == null) {
+            throw new IllegalArgumentException(
+                    "Grid column reference can not be null!");
+        }
+        if (direction == null) {
+            throw new IllegalArgumentException(
+                    "Direction value can not be null!");
+        }
+        this.column = column;
+        this.direction = direction;
+    }
+
+    /**
+     * Returns the {@link GridColumn} reference given in the constructor.
+     *
+     * @return a grid column reference
+     */
+    public GridColumn<?, ?> getColumn() {
+        return column;
+    }
+
+    /**
+     * Returns the {@link SortDirection} value given in the constructor.
+     *
+     * @return a sort direction value
+     */
+    public SortDirection getDirection() {
+        return direction;
+    }
+
+}
index 5c5e88bf6937bcfa8a8d93efd9f587c0e7417917..823eb224ea39173efe329d356f9e101e32b3cdfd 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * 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
 package com.vaadin.client.ui.grid;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Arrays;
+import java.util.Comparator;
 
 import org.easymock.EasyMock;
 import org.junit.Test;
@@ -26,7 +28,7 @@ import com.vaadin.client.data.DataChangeHandler;
 import com.vaadin.client.ui.grid.datasources.ListDataSource;
 
 /**
- * 
+ *
  * @since 7.2
  * @author Vaadin Ltd
  */
@@ -175,4 +177,21 @@ public class ListDataSourceTest {
         ds.asList().iterator().remove();
     }
 
+    @Test
+    public void sortColumn() {
+        ListDataSource<Integer> ds = new ListDataSource<Integer>(3, 4, 2, 3, 1);
+
+        // TODO Should be simplified to sort(). No point in providing these
+        // trivial comparators.
+        ds.sort(new Comparator<Integer>() {
+            @Override
+            public int compare(Integer o1, Integer o2) {
+                return o1.compareTo(o2);
+            }
+        });
+
+        assertTrue(Arrays.equals(ds.asList().toArray(), new Integer[] { 1, 2,
+                3, 3, 4 }));
+    }
+
 }
diff --git a/shared/src/com/vaadin/shared/ui/grid/SortDirection.java b/shared/src/com/vaadin/shared/ui/grid/SortDirection.java
new file mode 100644 (file)
index 0000000..3a18289
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 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.shared.ui.grid;
+
+/**
+ * Describes sorting direction for a Grid column
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public enum SortDirection {
+
+    /**
+     * Ascending (e.g. A-Z, 1..9) sort order
+     */
+    ASCENDING,
+
+    /**
+     * Descending (e.g. Z-A, 9..1) sort order
+     */
+    DESCENDING
+}
index 15bd323e0833ced44624d786e126b588df335315..91a4e19886113544d565c1f14ea27f5a6abaae62 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2000-2014 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
@@ -24,6 +24,7 @@ import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
 import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.testbench.elements.NativeButtonElement;
 import com.vaadin.testbench.elements.NativeSelectElement;
 import com.vaadin.testbench.elements.ServerClass;
@@ -33,7 +34,7 @@ import com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers;
 
 /**
  * Tests Grid client side renderers
- * 
+ *
  * @since 7.4
  * @author Vaadin Ltd
  */
@@ -161,6 +162,21 @@ public class GridClientRenderers extends MultiBrowserTest {
                 backgroundColor);
     }
 
+    @Test
+    public void testSortingEvent() throws Exception {
+        openTestURL();
+
+        $(NativeButtonElement.class).caption("Trigger sorting").first().click();
+        sleep(1000);
+
+        String consoleText = $(LabelElement.class).id("testDebugConsole")
+                .getText();
+
+        assertTrue("Console text as expected",
+                consoleText.contains("Columns: 1, order: Column 1: ASCENDING"));
+
+    }
+
     private GridElement getGrid() {
         return $(MyClientGridElement.class).first();
     }
index 24e79d775f55eeeb36f9297cf7d3cca9a39ca3d2..c07f6192b25b557cef9405093e0735a087925fe3 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2000-2014 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
@@ -19,6 +19,8 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.Timer;
@@ -39,6 +41,10 @@ import com.vaadin.client.ui.grid.renderers.HtmlRenderer;
 import com.vaadin.client.ui.grid.renderers.NumberRenderer;
 import com.vaadin.client.ui.grid.renderers.TextRenderer;
 import com.vaadin.client.ui.grid.renderers.WidgetRenderer;
+import com.vaadin.client.ui.grid.sort.Sort;
+import com.vaadin.client.ui.grid.sort.SortEvent;
+import com.vaadin.client.ui.grid.sort.SortEventHandler;
+import com.vaadin.client.ui.grid.sort.SortOrder;
 import com.vaadin.shared.ui.Connect;
 import com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers;
 
@@ -109,7 +115,7 @@ public class GridClientColumnRendererConnector extends
     @Override
     protected void init() {
         Grid<String> grid = getWidget();
-        grid.setColumnHeadersVisible(false);
+        // grid.setColumnHeadersVisible(false);
 
         // Generated some column data
         List<String> columnData = new ArrayList<String>();
@@ -127,7 +133,25 @@ public class GridClientColumnRendererConnector extends
         }
 
         // Add a column to display the data in
-        grid.addColumn(createColumnWithRenderer(Renderers.TEXT_RENDERER));
+        GridColumn<String, String> c = createColumnWithRenderer(Renderers.TEXT_RENDERER);
+        c.setHeaderCaption("Column 1");
+        grid.addColumn(c);
+
+        // Add method for testing sort event firing
+        grid.addSortHandler(new SortEventHandler<String>() {
+            @Override
+            public void sort(SortEvent<String> event) {
+                Element console = Document.get().getElementById(
+                        "testDebugConsole");
+                String text = "Client-side sort event received<br>"
+                        + "Columns: " + event.getOrder().size() + ", order: ";
+                for (SortOrder order : event.getOrder()) {
+                    text += order.getColumn().getHeaderCaption() + ": "
+                            + order.getDirection().toString();
+                }
+                console.setInnerHTML(text);
+            }
+        });
 
         // Handle RPC calls
         registerRpc(GridClientColumnRendererRpc.class,
@@ -160,6 +184,11 @@ public class GridClientColumnRendererConnector extends
                         // Re-attach
                         parent.add(getWidget());
                     }
+
+                    @Override
+                    public void triggerClientSorting() {
+                        getWidget().sort(Sort.by(getWidget().getColumn(0)));
+                    }
                 });
     }
 
index d156bf9b886aab15e198f29c79456a9d1871645d..ade239466e98f9675b18d2346505627e9543e5d1 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2000-2014 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
@@ -22,7 +22,7 @@ public interface GridClientColumnRendererRpc extends ClientRpc {
 
     /**
      * Adds a new column with a specific renderer to the grid
-     * 
+     *
      */
     void addColumn(Renderers renderer);
 
@@ -30,4 +30,9 @@ public interface GridClientColumnRendererRpc extends ClientRpc {
      * Detaches and attaches the client side Grid
      */
     void detachAttach();
+
+    /**
+     * Used for client-side sorting API test
+     */
+    void triggerClientSorting();
 }
index e968f13ff5e75cc81396879a58999dceba7efb2b..d41370cc02725ad3dfb93e5cdc7c11c1b226d227 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2000-2014 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
@@ -19,6 +19,7 @@ import java.util.Arrays;
 
 import com.vaadin.annotations.Widgetset;
 import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.label.ContentMode;
 import com.vaadin.tests.widgetset.TestingWidgetSet;
 import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererConnector.Renderers;
 import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererRpc;
@@ -26,6 +27,7 @@ import com.vaadin.ui.AbstractComponent;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.Button.ClickListener;
 import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Label;
 import com.vaadin.ui.NativeButton;
 import com.vaadin.ui.NativeSelect;
 import com.vaadin.ui.UI;
@@ -56,6 +58,13 @@ public class GridClientColumnRenderers extends UI {
         public void detachAttach() {
             rpc().detachAttach();
         }
+
+        /**
+         * @since
+         */
+        public void triggerClientSorting() {
+            rpc().triggerClientSorting();
+        }
     }
 
     @Override
@@ -94,5 +103,19 @@ public class GridClientColumnRenderers extends UI {
             }
         });
         controls.addComponent(detachAttachBtn);
+
+        NativeButton sortButton = new NativeButton("Trigger sorting");
+        sortButton.addClickListener(new ClickListener() {
+            @Override
+            public void buttonClick(ClickEvent event) {
+                controller.triggerClientSorting();
+            }
+        });
+        controls.addComponent(sortButton);
+
+        Label console = new Label();
+        console.setContentMode(ContentMode.HTML);
+        console.setId("testDebugConsole");
+        content.addComponent(console);
     }
 }