]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add server-side API for column freezing (#3087)
authorHenrik Paul <henrik@vaadin.com>
Sun, 24 Nov 2013 14:38:16 +0000 (16:38 +0200)
committerVaadin Code Review <review@vaadin.com>
Sun, 24 Nov 2013 15:16:21 +0000 (15:16 +0000)
Change-Id: I4704ab2bd2b1af31b4586e26cf89f03d97f136a4

client/src/com/vaadin/client/ui/grid/Grid.java
client/src/com/vaadin/client/ui/grid/GridConnector.java
server/src/com/vaadin/ui/components/grid/Grid.java
server/src/com/vaadin/ui/components/grid/GridColumn.java
server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
shared/src/com/vaadin/shared/ui/grid/GridState.java
uitest/src/com/vaadin/tests/components/grid/GridBasicFeatures.java

index d76424ae31b169450a9eb29fdd16754fb2b3de91..90c8b60474b66fbe103386c6fd18f300ff14446a 100644 (file)
@@ -83,6 +83,8 @@ public class Grid<T> extends Composite {
      */
     private boolean columnFootersVisible = false;
 
+    private GridColumn<T> lastFrozenColumn;
+
     /**
      * Base class for grid columns internally used by the Grid. The user should
      * use {@link GridColumn} when creating new columns.
@@ -560,6 +562,12 @@ public class Grid<T> extends Composite {
 
         ColumnConfiguration conf = escalator.getColumnConfiguration();
         conf.insertColumns(index, 1);
+
+        if (lastFrozenColumn != null
+                && ((AbstractGridColumn<T>) lastFrozenColumn)
+                        .findIndexOfColumn() < index) {
+            refreshFrozenColumns();
+        }
     }
 
     /**
@@ -578,6 +586,12 @@ public class Grid<T> extends Composite {
 
         ColumnConfiguration conf = escalator.getColumnConfiguration();
         conf.removeColumns(columnIndex, 1);
+
+        if (column.equals(lastFrozenColumn)) {
+            setLastFrozenColumn(null);
+        } else {
+            refreshFrozenColumns();
+        }
     }
 
     /**
@@ -861,4 +875,50 @@ public class Grid<T> extends Composite {
             escalator.getBody().insertRows(0, estimatedSize);
         }
     }
+
+    /**
+     * Sets the rightmost frozen column in the grid.
+     * <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
+     * @throws IllegalArgumentException
+     *             if {@code lastFrozenColumn} is not a column from this grid
+     */
+    public void setLastFrozenColumn(GridColumn<T> lastFrozenColumn) {
+        this.lastFrozenColumn = lastFrozenColumn;
+        refreshFrozenColumns();
+    }
+
+    private void refreshFrozenColumns() {
+        final int frozenCount;
+        if (lastFrozenColumn != null) {
+            frozenCount = columns.indexOf(lastFrozenColumn) + 1;
+            if (frozenCount == 0) {
+                throw new IllegalArgumentException(
+                        "The given column isn't attached to this grid");
+            }
+        } else {
+            frozenCount = 0;
+        }
+
+        escalator.getColumnConfiguration().setFrozenColumnCount(frozenCount);
+    }
+
+    /**
+     * Gets the rightmost frozen column in the grid.
+     * <p>
+     * <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.
+     */
+    public GridColumn<T> getLastFrozenColumn() {
+        return lastFrozenColumn;
+    }
 }
index 896a9998fb1ad5c994b8d1afc9ceccd270cf9d3e..befbc5a50ba8336968a56d6e68527e87226f45d7 100644 (file)
@@ -125,6 +125,18 @@ public class GridConnector extends AbstractComponentConnector {
         if (stateChangeEvent.hasPropertyChanged("columnGroupRows")) {
             updateColumnGroupsFromStateChangeEvent();
         }
+
+        if (stateChangeEvent.hasPropertyChanged("lastFrozenColumnId")) {
+            String frozenColId = getState().lastFrozenColumnId;
+            if (frozenColId != null) {
+                CustomGridColumn column = columnIdToColumn.get(frozenColId);
+                assert column != null : "Column to be frozen could not be found (id:"
+                        + frozenColId + ")";
+                getWidget().setLastFrozenColumn(column);
+            } else {
+                getWidget().setLastFrozenColumn(null);
+            }
+        }
     }
 
     /**
index 79cc05e1a0078a406c41c1b494e9a2a039369864..1fb0692104bd3202e41d3395b29d669415727f72 100644 (file)
@@ -105,6 +105,12 @@ public class Grid extends AbstractComponent {
                     appendColumn(propertyId);
                 }
             }
+
+            Object frozenPropertyId = columnKeys
+                    .get(getState(false).lastFrozenColumnId);
+            if (!columns.containsKey(frozenPropertyId)) {
+                setLastFrozenPropertyId(null);
+            }
         }
     };
 
@@ -158,6 +164,7 @@ public class Grid extends AbstractComponent {
         }
 
         getState().columns.clear();
+        setLastFrozenPropertyId(null);
 
         // Add columns
         for (Object propertyId : datasource.getContainerPropertyIds()) {
@@ -362,4 +369,79 @@ public class Grid extends AbstractComponent {
 
         return column;
     }
+
+    /**
+     * Sets (or unsets) the rightmost frozen column in the grid.
+     * <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
+     * @throws IllegalArgumentException
+     *             if {@code lastFrozenColumn} is not a column from this grid
+     */
+    void setLastFrozenColumn(GridColumn lastFrozenColumn) {
+        /*
+         * TODO: If and when Grid supports column reordering or insertion of
+         * columns before other columns, make sure to mention that adding
+         * columns before lastFrozenColumn will change the frozen column count
+         */
+
+        if (lastFrozenColumn == null) {
+            getState().lastFrozenColumnId = null;
+        } else if (columns.containsValue(lastFrozenColumn)) {
+            getState().lastFrozenColumnId = lastFrozenColumn.getState().id;
+        } else {
+            throw new IllegalArgumentException(
+                    "The given column isn't attached to this grid");
+        }
+    }
+
+    /**
+     * Sets (or unsets) the rightmost frozen column in the grid.
+     * <p>
+     * All columns up to and including the indicated property will be frozen in
+     * place when the grid is scrolled sideways.
+     * <p>
+     * <em>Note:</em> If the container used by this grid supports a propertyId
+     * <code>null</code>, it can never be defined as the last frozen column, as
+     * a <code>null</code> parameter will always reset the frozen columns in
+     * Grid.
+     * 
+     * @param propertyId
+     *            the property id corresponding to the column that should be the
+     *            last frozen column, or <code>null</code> to not have any
+     *            columns frozen.
+     * @throws IllegalArgumentException
+     *             if {@code lastFrozenColumn} is not a column from this grid
+     */
+    public void setLastFrozenPropertyId(Object propertyId) {
+        final GridColumn column;
+        if (propertyId == null) {
+            column = null;
+        } else {
+            column = getColumn(propertyId);
+            if (column == null) {
+                throw new IllegalArgumentException(
+                        "property id does not exist.");
+            }
+        }
+        setLastFrozenColumn(column);
+    }
+
+    /**
+     * Gets the rightmost frozen column in the grid.
+     * <p>
+     * <em>Note:</em> Most often, this method returns the very value set with
+     * {@link #setLastFrozenPropertyId(Object)}. This value, however, can be
+     * reset to <code>null</code> if the column is detached from this grid.
+     * 
+     * @return the rightmost frozen column in the grid, or <code>null</code> if
+     *         no columns are frozen.
+     */
+    public Object getLastFrozenPropertyId() {
+        return columnKeys.get(getState().lastFrozenColumnId);
+    }
 }
index dde066923898b455522f49ef2ddfc18610015e62..8dae9428e5d31b9c5a5d676bb21ae931bea9d5f9 100644 (file)
@@ -192,4 +192,16 @@ public class GridColumn implements Serializable {
             throw new IllegalStateException("Column no longer exists.");
         }
     }
+
+    /**
+     * Sets this column as the last frozen column in its grid.
+     * 
+     * @throws IllegalArgumentException
+     *             if the column is no longer attached to any grid
+     * @see Grid#setLastFrozenColumn(GridColumn)
+     */
+    public void setLastFrozenColumn() {
+        checkColumnIsAttached();
+        grid.setLastFrozenColumn(this);
+    }
 }
index 85864160a806b4dd09fe2b509408b78830ddd2ba..c129db0264c60461ec50389ac5f7326c2f83776a 100644 (file)
@@ -242,6 +242,20 @@ public class GridColumns {
         assertTrue(state.columnGroupRows.size() == 3);
     }
 
+    @Test
+    public void testFrozenColumnByPropertyId() {
+        assertNull("Grid should not start with a frozen column",
+                grid.getLastFrozenPropertyId());
+
+        Object propertyId = grid.getContainerDatasource()
+                .getContainerPropertyIds().iterator().next();
+        grid.setLastFrozenPropertyId(propertyId);
+        assertEquals(propertyId, grid.getLastFrozenPropertyId());
+
+        grid.getContainerDatasource().removeContainerProperty(propertyId);
+        assertNull(grid.getLastFrozenPropertyId());
+    }
+
     private GridColumnState getColumnState(Object propertyId) {
         String columnId = columnIdMapper.key(propertyId);
         for (GridColumnState columnState : state.columns) {
index d1167f3d4fbed83b27992792853d0d3a7dcb290f..93e602a53936593f8e3777fface2d9354f6ffbcd 100644 (file)
@@ -53,4 +53,12 @@ public class GridState extends AbstractComponentState {
      * The column groups added to the grid
      */
     public List<ColumnGroupRowState> columnGroupRows = new ArrayList<ColumnGroupRowState>();
+
+    /**
+     * The id for the last frozen column.
+     * 
+     * @see GridColumnState#id
+     */
+    public String lastFrozenColumnId = null;
+
 }
index 7bf5d65e8be67607085c3b77ce41233816a75106..afc9f91e68b8af8dbec3a917adf6176bec306f70 100644 (file)
@@ -133,6 +133,15 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> {
                         }
                     }, null, c);
 
+            createClickAction("Freeze", "Column" + c,
+                    new Command<Grid, String>() {
+
+                        @Override
+                        public void execute(Grid grid, String value, Object data) {
+                            grid.setLastFrozenPropertyId("Column" + data);
+                        }
+                    }, null, c);
+
         }
 
     }