From cff79054fb76f472eaf3d53d4da27fff6d1a95f7 Mon Sep 17 00:00:00 2001 From: Henrik Paul Date: Sun, 24 Nov 2013 16:38:16 +0200 Subject: [PATCH] Add server-side API for column freezing (#3087) Change-Id: I4704ab2bd2b1af31b4586e26cf89f03d97f136a4 --- .../src/com/vaadin/client/ui/grid/Grid.java | 60 ++++++++++++++ .../vaadin/client/ui/grid/GridConnector.java | 12 +++ .../com/vaadin/ui/components/grid/Grid.java | 82 +++++++++++++++++++ .../vaadin/ui/components/grid/GridColumn.java | 12 +++ .../server/component/grid/GridColumns.java | 14 ++++ .../com/vaadin/shared/ui/grid/GridState.java | 8 ++ .../components/grid/GridBasicFeatures.java | 9 ++ 7 files changed, 197 insertions(+) diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java index d76424ae31..90c8b60474 100644 --- a/client/src/com/vaadin/client/ui/grid/Grid.java +++ b/client/src/com/vaadin/client/ui/grid/Grid.java @@ -83,6 +83,8 @@ public class Grid extends Composite { */ private boolean columnFootersVisible = false; + private GridColumn 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 extends Composite { ColumnConfiguration conf = escalator.getColumnConfiguration(); conf.insertColumns(index, 1); + + if (lastFrozenColumn != null + && ((AbstractGridColumn) lastFrozenColumn) + .findIndexOfColumn() < index) { + refreshFrozenColumns(); + } } /** @@ -578,6 +586,12 @@ public class Grid 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 extends Composite { escalator.getBody().insertRows(0, estimatedSize); } } + + /** + * Sets the rightmost frozen column in the grid. + *

+ * 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 null to not + * have any columns frozen + * @throws IllegalArgumentException + * if {@code lastFrozenColumn} is not a column from this grid + */ + public void setLastFrozenColumn(GridColumn 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. + *

+ * Note: Most usually, this method returns the very value set with + * {@link #setLastFrozenColumn(GridColumn)}. This value, however, can be + * reset to null if the column is removed from this grid. + * + * @return the rightmost frozen column in the grid, or null if + * no columns are frozen. + */ + public GridColumn getLastFrozenColumn() { + return lastFrozenColumn; + } } diff --git a/client/src/com/vaadin/client/ui/grid/GridConnector.java b/client/src/com/vaadin/client/ui/grid/GridConnector.java index 896a9998fb..befbc5a50b 100644 --- a/client/src/com/vaadin/client/ui/grid/GridConnector.java +++ b/client/src/com/vaadin/client/ui/grid/GridConnector.java @@ -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); + } + } } /** diff --git a/server/src/com/vaadin/ui/components/grid/Grid.java b/server/src/com/vaadin/ui/components/grid/Grid.java index 79cc05e1a0..1fb0692104 100644 --- a/server/src/com/vaadin/ui/components/grid/Grid.java +++ b/server/src/com/vaadin/ui/components/grid/Grid.java @@ -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. + *

+ * 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 null 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. + *

+ * All columns up to and including the indicated property will be frozen in + * place when the grid is scrolled sideways. + *

+ * Note: If the container used by this grid supports a propertyId + * null, it can never be defined as the last frozen column, as + * a null 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 null 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. + *

+ * Note: Most often, this method returns the very value set with + * {@link #setLastFrozenPropertyId(Object)}. This value, however, can be + * reset to null if the column is detached from this grid. + * + * @return the rightmost frozen column in the grid, or null if + * no columns are frozen. + */ + public Object getLastFrozenPropertyId() { + return columnKeys.get(getState().lastFrozenColumnId); + } } diff --git a/server/src/com/vaadin/ui/components/grid/GridColumn.java b/server/src/com/vaadin/ui/components/grid/GridColumn.java index dde0669238..8dae9428e5 100644 --- a/server/src/com/vaadin/ui/components/grid/GridColumn.java +++ b/server/src/com/vaadin/ui/components/grid/GridColumn.java @@ -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); + } } diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java index 85864160a8..c129db0264 100644 --- a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java +++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java @@ -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) { diff --git a/shared/src/com/vaadin/shared/ui/grid/GridState.java b/shared/src/com/vaadin/shared/ui/grid/GridState.java index d1167f3d4f..93e602a539 100644 --- a/shared/src/com/vaadin/shared/ui/grid/GridState.java +++ b/shared/src/com/vaadin/shared/ui/grid/GridState.java @@ -53,4 +53,12 @@ public class GridState extends AbstractComponentState { * The column groups added to the grid */ public List columnGroupRows = new ArrayList(); + + /** + * The id for the last frozen column. + * + * @see GridColumnState#id + */ + public String lastFrozenColumnId = null; + } diff --git a/uitest/src/com/vaadin/tests/components/grid/GridBasicFeatures.java b/uitest/src/com/vaadin/tests/components/grid/GridBasicFeatures.java index 7bf5d65e8b..afc9f91e68 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridBasicFeatures.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridBasicFeatures.java @@ -133,6 +133,15 @@ public class GridBasicFeatures extends AbstractComponentTest { } }, null, c); + createClickAction("Freeze", "Column" + c, + new Command() { + + @Override + public void execute(Grid grid, String value, Object data) { + grid.setLastFrozenPropertyId("Column" + data); + } + }, null, c); + } } -- 2.39.5