From 5d0aa11b2c83e7f5abfa4c6d9ef71871b810a016 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Tue, 29 Jul 2014 17:19:28 +0300 Subject: [PATCH] Add server side API for Headers and Footers (#13334) Change-Id: I52f282089cc55b1f281b9aeb934886442b0c34f3 --- .../com/vaadin/ui/components/grid/Grid.java | 66 +++-- .../vaadin/ui/components/grid/GridColumn.java | 17 +- .../vaadin/ui/components/grid/GridFooter.java | 66 +++++ .../vaadin/ui/components/grid/GridHeader.java | 124 ++++++++ .../ui/components/grid/GridStaticSection.java | 273 ++++++++++++++++++ .../server/component/grid/GridColumns.java | 32 +- .../grid/basicfeatures/GridBasicFeatures.java | 135 ++++++++- .../GridKeyboardNavigationTest.java | 4 +- .../grid/basicfeatures/GridSortingTest.java | 33 +-- .../grid/basicfeatures/GridStructureTest.java | 37 +-- 10 files changed, 679 insertions(+), 108 deletions(-) create mode 100644 server/src/com/vaadin/ui/components/grid/GridFooter.java create mode 100644 server/src/com/vaadin/ui/components/grid/GridHeader.java create mode 100644 server/src/com/vaadin/ui/components/grid/GridStaticSection.java diff --git a/server/src/com/vaadin/ui/components/grid/Grid.java b/server/src/com/vaadin/ui/components/grid/Grid.java index 67a97c74b7..f5846c0148 100644 --- a/server/src/com/vaadin/ui/components/grid/Grid.java +++ b/server/src/com/vaadin/ui/components/grid/Grid.java @@ -46,12 +46,11 @@ import com.vaadin.shared.ui.grid.GridColumnState; import com.vaadin.shared.ui.grid.GridServerRpc; import com.vaadin.shared.ui.grid.GridState; import com.vaadin.shared.ui.grid.GridState.SharedSelectionMode; -import com.vaadin.shared.ui.grid.GridStaticSectionState.CellState; -import com.vaadin.shared.ui.grid.GridStaticSectionState.RowState; import com.vaadin.shared.ui.grid.HeightMode; import com.vaadin.shared.ui.grid.ScrollDestination; import com.vaadin.shared.ui.grid.SortDirection; import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.components.grid.GridHeader.HeaderRow; import com.vaadin.ui.components.grid.selection.MultiSelectionModel; import com.vaadin.ui.components.grid.selection.NoSelectionModel; import com.vaadin.ui.components.grid.selection.SelectionChangeEvent; @@ -209,6 +208,9 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { */ private int ignoreSelectionClientSync = 0; + private final GridHeader header = new GridHeader(this); + private final GridFooter footer = new GridFooter(this); + private static final Method SELECTION_CHANGE_METHOD = ReflectTools .findMethod(SelectionChangeListener.class, "selectionChange", SelectionChangeEvent.class); @@ -224,17 +226,8 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * the data source for the grid */ public Grid(final Container.Indexed datasource) { - - RowState headerDefaultRow = new RowState(); - headerDefaultRow.defaultRow = true; - getState().header.rows.add(headerDefaultRow); - - // FIXME By default there shouldn't be any footer row - getState().footer.rows.add(new RowState()); - - setColumnFootersVisible(false); - setContainerDataSource(datasource); + setSelectionMode(SelectionMode.MULTI); addSelectionChangeListener(new SelectionChangeListener() { @Override @@ -433,6 +426,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { setLastFrozenPropertyId(null); // Add columns + HeaderRow row = getHeader().getDefaultRow(); for (Object propertyId : datasource.getContainerPropertyIds()) { if (!columns.containsKey(propertyId)) { GridColumn column = appendColumn(propertyId); @@ -445,7 +439,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { } // Add by default property id as column header - column.setHeaderCaption(String.valueOf(propertyId)); + row.getCell(propertyId).setText(String.valueOf(propertyId)); } } } @@ -476,8 +470,9 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * @param visible * true if the header rows should be visible */ + @Deprecated public void setColumnHeadersVisible(boolean visible) { - getState().header.visible = visible; + getHeader().setVisible(visible); } /** @@ -485,8 +480,9 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * * @return true if the headers of the columns are visible */ + @Deprecated public boolean isColumnHeadersVisible() { - return getState(false).header.visible; + return getHeader().isVisible(); } /** @@ -495,8 +491,9 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * @param visible * true if the footer rows should be visible */ + @Deprecated public void setColumnFootersVisible(boolean visible) { - getState().footer.visible = visible; + getFooter().setVisible(visible); } /** @@ -504,8 +501,9 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * * @return true if the footer rows should be visible */ + @Deprecated public boolean isColumnFootersVisible() { - return getState(false).footer.visible; + return getFooter().isVisible(); } /** @@ -537,6 +535,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * * @return a column group instance you can use to add column groups */ + @Deprecated public ColumnGroupRow addColumnGroupRow() { ColumnGroupRowState state = new ColumnGroupRowState(); ColumnGroupRow row = new ColumnGroupRow(this, state, columnKeys); @@ -552,6 +551,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * the index of the row * @return a column group instance you can use to add column groups */ + @Deprecated public ColumnGroupRow addColumnGroupRow(int rowIndex) { ColumnGroupRowState state = new ColumnGroupRowState(); ColumnGroupRow row = new ColumnGroupRow(this, state, columnKeys); @@ -566,6 +566,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * @param row * the row to remove */ + @Deprecated public void removeColumnGroupRow(ColumnGroupRow row) { columnGroupRows.remove(row); getState().columnGroupRows.remove(row.getState()); @@ -576,6 +577,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { * * @return an unmodifiable list of column group rows */ + @Deprecated public List getColumnGroupRows() { return Collections.unmodifiableList(new ArrayList( columnGroupRows)); @@ -635,11 +637,13 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { GridColumnState columnState = new GridColumnState(); columnState.id = columnKeys.key(datasourcePropertyId); getState().columns.add(columnState); - for (RowState row : getState().header.rows) { - row.cells.add(new CellState()); + + for (int i = 0; i < getHeader().getRowCount(); ++i) { + getHeader().getRow(i).addCell(datasourcePropertyId); } - for (RowState row : getState().footer.rows) { - row.cells.add(new CellState()); + + for (int i = 0; i < getFooter().getRowCount(); ++i) { + getFooter().getRow(i).addCell(datasourcePropertyId); } GridColumn column = new GridColumn(this, columnState); @@ -1316,4 +1320,24 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier { removeListener(SortOrderChangeEvent.class, listener, SORT_ORDER_CHANGE_METHOD); } + + /** + * Returns the header section of this grid. The default header contains a + * single row displaying the column captions. + * + * @return the header + */ + public GridHeader getHeader() { + return header; + } + + /** + * Returns the footer section of this grid. The default header contains a + * single row displaying the column captions. + * + * @return the footer + */ + public GridFooter getFooter() { + return footer; + } } diff --git a/server/src/com/vaadin/ui/components/grid/GridColumn.java b/server/src/com/vaadin/ui/components/grid/GridColumn.java index 667b4f86db..0ef805eb2e 100644 --- a/server/src/com/vaadin/ui/components/grid/GridColumn.java +++ b/server/src/com/vaadin/ui/components/grid/GridColumn.java @@ -82,14 +82,15 @@ public class GridColumn implements Serializable { * Returns the caption of the header. By default the header caption is the * property id of the column. * - * @return the text in the header + * @return the text in the default row of header, null if no default row * * @throws IllegalStateException * if the column no longer is attached to the grid */ + @Deprecated public String getHeaderCaption() throws IllegalStateException { checkColumnIsAttached(); - return getHeaderCellState().text; + return state.header; } /** @@ -101,11 +102,10 @@ public class GridColumn implements Serializable { * @throws IllegalStateException * if the column is no longer attached to any grid */ + @Deprecated public void setHeaderCaption(String caption) throws IllegalStateException { checkColumnIsAttached(); - getHeaderCellState().text = caption; state.header = caption; - grid.markAsDirty(); } /** @@ -116,6 +116,7 @@ public class GridColumn implements Serializable { * @throws IllegalStateException * if the column is no longer attached to any grid */ + @Deprecated public String getFooterCaption() throws IllegalStateException { checkColumnIsAttached(); return getFooterCellState().text; @@ -130,6 +131,7 @@ public class GridColumn implements Serializable { * @throws IllegalStateException * if the column is no longer attached to any grid */ + @Deprecated public void setFooterCaption(String caption) throws IllegalStateException { checkColumnIsAttached(); getFooterCellState().text = caption; @@ -137,11 +139,6 @@ public class GridColumn implements Serializable { grid.markAsDirty(); } - private CellState getHeaderCellState() { - int index = grid.getState().columns.indexOf(state); - return grid.getState().header.rows.get(0).cells.get(index); - } - private CellState getFooterCellState() { int index = grid.getState().columns.indexOf(state); return grid.getState().footer.rows.get(0).cells.get(index); @@ -252,7 +249,7 @@ public class GridColumn implements Serializable { * the renderer to use * @throws IllegalArgumentException * if no compatible converter could be found - * + * * @see VaadinSession#getConverterFactory() * @see ConverterUtil#getConverter(Class, Class, VaadinSession) * @see #setConverter(Converter) diff --git a/server/src/com/vaadin/ui/components/grid/GridFooter.java b/server/src/com/vaadin/ui/components/grid/GridFooter.java new file mode 100644 index 0000000000..e4a7eab5d1 --- /dev/null +++ b/server/src/com/vaadin/ui/components/grid/GridFooter.java @@ -0,0 +1,66 @@ +/* + * 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.ui.components.grid; + +import com.vaadin.shared.ui.grid.GridStaticSectionState; + +/** + * Represents the footer section of a Grid. By default Footer is not visible. + * + * @since + * @author Vaadin Ltd + */ +public class GridFooter extends GridStaticSection { + + public class FooterRow extends GridStaticSection.StaticRow { + + protected FooterRow(GridStaticSection section) { + super(section); + } + + @Override + protected FooterCell createCell() { + return new FooterCell(this); + } + + } + + public class FooterCell extends GridStaticSection.StaticCell { + + protected FooterCell(FooterRow row) { + super(row); + } + } + + private final GridStaticSectionState footerState = new GridStaticSectionState(); + + protected GridFooter(Grid grid) { + this.grid = grid; + grid.getState(true).footer = footerState; + setVisible(false); + } + + @Override + protected GridStaticSectionState getState() { + return footerState; + } + + @Override + protected FooterRow createRow() { + return new FooterRow(this); + } + +} diff --git a/server/src/com/vaadin/ui/components/grid/GridHeader.java b/server/src/com/vaadin/ui/components/grid/GridHeader.java new file mode 100644 index 0000000000..f8bd3c6642 --- /dev/null +++ b/server/src/com/vaadin/ui/components/grid/GridHeader.java @@ -0,0 +1,124 @@ +/* + * 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.ui.components.grid; + +import com.vaadin.shared.ui.grid.GridStaticSectionState; + +/** + * Represents the header section of a Grid. + * + * @since + * @author Vaadin Ltd + */ +public class GridHeader extends GridStaticSection { + + public class HeaderRow extends GridStaticSection.StaticRow { + + protected HeaderRow(GridStaticSection section) { + super(section); + } + + private void setDefaultRow(boolean value) { + getRowState().defaultRow = value; + } + + @Override + protected HeaderCell createCell() { + return new HeaderCell(this); + } + } + + public class HeaderCell extends GridStaticSection.StaticCell { + + protected HeaderCell(HeaderRow row) { + super(row); + } + } + + private HeaderRow defaultRow = null; + private final GridStaticSectionState headerState = new GridStaticSectionState(); + + protected GridHeader(Grid grid) { + this.grid = grid; + grid.getState(true).header = headerState; + HeaderRow row = createRow(); + rows.add(row); + setDefaultRow(row); + getState().rows.add(row.getRowState()); + } + + /** + * Sets the default row of this header. The default row is a special header + * row providing a user interface for sorting columns. + * + * @param row + * the new default row, or null for no default row + * + * @throws IllegalArgumentException + * this header does not contain the row + */ + public void setDefaultRow(HeaderRow row) { + if (row == defaultRow) { + return; + } + + if (row != null && !rows.contains(row)) { + throw new IllegalArgumentException( + "Cannot set a default row that does not exist in the section"); + } + + if (defaultRow != null) { + defaultRow.setDefaultRow(false); + } + + if (row != null) { + row.setDefaultRow(true); + } + + defaultRow = row; + markAsDirty(); + } + + /** + * Returns the current default row of this header. The default row is a + * special header row providing a user interface for sorting columns. + * + * @return the default row or null if no default row set + */ + public HeaderRow getDefaultRow() { + return defaultRow; + } + + @Override + protected GridStaticSectionState getState() { + return headerState; + } + + @Override + protected HeaderRow createRow() { + return new HeaderRow(this); + } + + @Override + public HeaderRow removeRow(int rowIndex) { + HeaderRow row = super.removeRow(rowIndex); + if (row == defaultRow) { + // Default Header Row was just removed. + setDefaultRow(null); + } + return row; + } +} diff --git a/server/src/com/vaadin/ui/components/grid/GridStaticSection.java b/server/src/com/vaadin/ui/components/grid/GridStaticSection.java new file mode 100644 index 0000000000..80d822e7bc --- /dev/null +++ b/server/src/com/vaadin/ui/components/grid/GridStaticSection.java @@ -0,0 +1,273 @@ +/* + * 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.ui.components.grid; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.vaadin.data.Container.Indexed; +import com.vaadin.shared.ui.grid.GridStaticSectionState; +import com.vaadin.shared.ui.grid.GridStaticSectionState.CellState; +import com.vaadin.shared.ui.grid.GridStaticSectionState.RowState; + +/** + * Abstract base class for Grid header and footer sections. + * + * @since + * @author Vaadin Ltd + * @param + * the type of the rows in the section + */ +abstract class GridStaticSection> + implements Serializable { + + /** + * Abstract base class for Grid header and footer rows. + * + * @param + * the type of the cells in the row + */ + abstract static class StaticRow> implements + Serializable { + + private RowState rowState = new RowState(); + protected GridStaticSection section; + private Map cells = new LinkedHashMap(); + + protected StaticRow(GridStaticSection section) { + this.section = section; + } + + protected void addCell(Object propertyId) { + CELLTYPE cell = createCell(); + cells.put(propertyId, cell); + rowState.cells.add(cell.getCellState()); + } + + /** + * Creates and returns a new instance of the cell type. + * + * @return the created cell + */ + protected abstract CELLTYPE createCell(); + + protected RowState getRowState() { + return rowState; + } + + /** + * Returns the cell at the given position in this row. + * + * @param propertyId + * the itemId of column + * @return the cell on given column + * @throws IndexOutOfBoundsException + * if the index is out of bounds + */ + public CELLTYPE getCell(Object propertyId) { + return cells.get(propertyId); + } + } + + /** + * A header or footer cell. Has a simple textual caption. + * + * @param + * the type of row this cells is in + */ + abstract static class StaticCell> implements + Serializable { + + private CellState cellState = new CellState(); + private ROWTYPE row; + + protected StaticCell(ROWTYPE row) { + this.row = row; + } + + /** + * Gets the row where this cell is. + * + * @return row for this cell + */ + public ROWTYPE getRow() { + return row; + } + + protected CellState getCellState() { + return cellState; + } + + /** + * Gets the current text content of this cell. Text is null if HTML or + * Component content is used. + * + * @return text content or null + */ + public String getText() { + return cellState.text; + } + + /** + * Sets the current text content of this cell. + * + * @param text + * new text content + */ + public void setText(String text) { + if (text != null && !text.equals(getCellState().text)) { + getCellState().text = text; + row.section.markAsDirty(); + } + } + } + + protected Grid grid; + protected List rows = new ArrayList(); + + /** + * Sets the visibility of the whole section. + * + * @param visible + * true to show this section, false to hide + */ + public void setVisible(boolean visible) { + if (getState().visible != visible) { + getState().visible = visible; + markAsDirty(); + } + } + + /** + * Returns the visibility of this section. + * + * @return true if visible, false otherwise. + */ + public boolean isVisible() { + return getState().visible; + } + + /** + * Removes the row at the given position. + * + * @param index + * the position of the row + * + * @throws IndexOutOfBoundsException + * if the index is out of bounds + */ + public ROWTYPE removeRow(int rowIndex) { + ROWTYPE row = rows.remove(rowIndex); + getState().rows.remove(rowIndex); + + markAsDirty(); + return row; + } + + /** + * Removes the given row from the section. + * + * @param row + * the row to be removed + * + * @throws IllegalArgumentException + * if the row does not exist in this section + */ + public void removeRow(ROWTYPE row) { + try { + removeRow(rows.indexOf(row)); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException( + "Section does not contain the given row"); + } + } + + /** + * Gets row at given index. + * + * @param rowIndex + * 0 based index for row. Counted from top to bottom + * @return row at given index + */ + public ROWTYPE getRow(int rowIndex) { + return rows.get(rowIndex); + } + + /** + * Adds a new row at the top of this section. + * + * @return the new row + */ + public ROWTYPE prependRow() { + return addRowAt(0); + } + + /** + * Adds a new row at the bottom of this section. + * + * @return the new row + */ + public ROWTYPE appendRow() { + return addRowAt(rows.size()); + } + + /** + * Inserts a new row at the given position. + * + * @param index + * the position at which to insert the row + * @return the new row + * + * @throws IndexOutOfBoundsException + * if the index is out of bounds + */ + public ROWTYPE addRowAt(int index) { + ROWTYPE row = createRow(); + rows.add(index, row); + getState().rows.add(index, row.getRowState()); + + Indexed dataSource = grid.getContainerDatasource(); + for (Object id : dataSource.getContainerPropertyIds()) { + row.addCell(id); + } + + markAsDirty(); + return row; + } + + /** + * Gets the amount of rows in this section. + * + * @return row count + */ + public int getRowCount() { + return rows.size(); + } + + protected abstract GridStaticSectionState getState(); + + protected abstract ROWTYPE createRow(); + + /** + * Informs the grid that state has changed and it should be redrawn. + */ + protected void markAsDirty() { + grid.markAsDirty(); + } +} 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 9d71d21d59..d1c821cc54 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 @@ -77,7 +77,8 @@ public class GridColumns { assertNotNull(column); // Property id should be the column header by default - assertEquals(propertyId.toString(), column.getHeaderCaption()); + assertEquals(propertyId.toString(), grid.getHeader() + .getDefaultRow().getCell(propertyId).getText()); } } @@ -88,11 +89,6 @@ public class GridColumns { GridColumn column = grid.getColumn("column1"); assertNotNull(column); - column.setFooterCaption("CustomFooter"); - assertEquals("CustomFooter", column.getFooterCaption()); - assertEquals(column.getFooterCaption(), - getColumnState("column1").footer); - column.setHeaderCaption("CustomHeader"); assertEquals("CustomHeader", column.getHeaderCaption()); assertEquals(column.getHeaderCaption(), @@ -174,31 +170,31 @@ public class GridColumns { @Test public void testHeaderVisiblility() throws Exception { - assertTrue(grid.isColumnHeadersVisible()); + assertTrue(grid.getHeader().isVisible()); assertTrue(state.header.visible); - grid.setColumnHeadersVisible(false); - assertFalse(grid.isColumnHeadersVisible()); + grid.getHeader().setVisible(false); + assertFalse(grid.getHeader().isVisible()); assertFalse(state.header.visible); - grid.setColumnHeadersVisible(true); - assertTrue(grid.isColumnHeadersVisible()); + grid.getHeader().setVisible(true); + assertTrue(grid.getHeader().isVisible()); assertTrue(state.header.visible); } @Test public void testFooterVisibility() throws Exception { - assertFalse(grid.isColumnFootersVisible()); - assertFalse(state.footer.visible); - - grid.setColumnFootersVisible(false); - assertFalse(grid.isColumnFootersVisible()); + assertFalse(grid.getFooter().isVisible()); assertFalse(state.footer.visible); - grid.setColumnFootersVisible(true); - assertTrue(grid.isColumnFootersVisible()); + grid.getFooter().setVisible(true); + assertTrue(grid.getFooter().isVisible()); assertTrue(state.footer.visible); + + grid.getFooter().setVisible(false); + assertFalse(grid.getFooter().isVisible()); + assertFalse(state.footer.visible); } @Test diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java index cfe3646295..bff16d8db7 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java @@ -36,6 +36,9 @@ import com.vaadin.ui.components.grid.ColumnGroupRow; import com.vaadin.ui.components.grid.Grid; import com.vaadin.ui.components.grid.Grid.SelectionMode; import com.vaadin.ui.components.grid.GridColumn; +import com.vaadin.ui.components.grid.GridFooter; +import com.vaadin.ui.components.grid.GridHeader; +import com.vaadin.ui.components.grid.GridHeader.HeaderRow; import com.vaadin.ui.components.grid.SortOrderChangeEvent; import com.vaadin.ui.components.grid.SortOrderChangeListener; import com.vaadin.ui.components.grid.renderers.DateRenderer; @@ -142,15 +145,20 @@ public class GridBasicFeatures extends AbstractComponentTest { new NumberRenderer()); } + // Create footer + GridFooter footer = grid.getFooter(); + footer.appendRow(); + footer.setVisible(false); + // Add footer values (header values are automatically created) for (int col = 0; col < COLUMNS; col++) { - grid.getColumn(getColumnProperty(col)).setFooterCaption( - "Footer " + col); + footer.getRow(0).getCell(getColumnProperty(col)) + .setText("Footer " + col); } // Set varying column widths for (int col = 0; col < COLUMNS; col++) { - grid.getColumn("Column" + col).setWidth(100 + col * 50); + grid.getColumn(getColumnProperty(col)).setWidth(100 + col * 50); } grid.addSortOrderChangeListener(new SortOrderChangeListener() { @@ -226,29 +234,125 @@ public class GridBasicFeatures extends AbstractComponentTest { } protected void createHeaderActions() { - createCategory("Headers", null); + createCategory("Header", null); - createBooleanAction("Visible", "Headers", true, + createBooleanAction("Visible", "Header", true, new Command() { @Override public void execute(Grid grid, Boolean value, Object data) { - grid.setColumnHeadersVisible(value); + grid.getHeader().setVisible(value); } }); + + LinkedHashMap defaultRows = new LinkedHashMap(); + defaultRows.put("Top", "Top"); + defaultRows.put("Bottom", "Bottom"); + defaultRows.put("Unset", "Unset"); + + createMultiClickAction("Default row", "Header", defaultRows, + new Command() { + + @Override + public void execute(Grid grid, String value, Object data) { + HeaderRow defaultRow = null; + GridHeader header = grid.getHeader(); + if (value.equals("Top")) { + defaultRow = header.getRow(0); + } else if (value.equals("Bottom")) { + defaultRow = header.getRow(header.getRowCount() - 1); + } + header.setDefaultRow(defaultRow); + } + + }, defaultRows.get("Top")); + + createClickAction("Prepend row", "Header", new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getHeader().prependRow(); + } + + }, null); + createClickAction("Append row", "Header", new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getHeader().appendRow(); + } + + }, null); + + createClickAction("Remove top row", "Header", + new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getHeader().removeRow(0); + } + + }, null); + createClickAction("Remove bottom row", "Header", + new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getHeader().removeRow( + grid.getHeader().getRowCount() - 1); + } + + }, null); } protected void createFooterActions() { - createCategory("Footers", null); + createCategory("Footer", null); - createBooleanAction("Visible", "Footers", false, + createBooleanAction("Visible", "Footer", false, new Command() { @Override public void execute(Grid grid, Boolean value, Object data) { - grid.setColumnFootersVisible(value); + grid.getFooter().setVisible(value); } }); + + createClickAction("Prepend row", "Footer", new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getFooter().prependRow(); + } + + }, null); + createClickAction("Append row", "Footer", new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getFooter().appendRow(); + } + + }, null); + + createClickAction("Remove top row", "Footer", + new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getFooter().removeRow(0); + } + + }, null); + createClickAction("Remove bottom row", "Footer", + new Command() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.getFooter().removeRow( + grid.getFooter().getRowCount() - 1); + } + + }, null); } protected void createColumnActions() { @@ -278,7 +382,8 @@ public class GridBasicFeatures extends AbstractComponentTest { @Override public void execute(Grid grid, String value, Object data) { grid.getContainerDatasource() - .removeContainerProperty("Column" + data); + .removeContainerProperty( + getColumnProperty((Integer) data)); } }, null, c); @@ -287,7 +392,7 @@ public class GridBasicFeatures extends AbstractComponentTest { @Override public void execute(Grid grid, String value, Object data) { - grid.setLastFrozenPropertyId("Column" + data); + grid.setLastFrozenPropertyId(getColumnProperty((Integer) data)); } }, null, c); @@ -306,9 +411,9 @@ public class GridBasicFeatures extends AbstractComponentTest { } }, c); - createCategory("Column" + c + " Width", getColumnProperty(c)); + createCategory("Column " + c + " Width", getColumnProperty(c)); - createClickAction("Auto", "Column" + c + " Width", + createClickAction("Auto", "Column " + c + " Width", new Command() { @Override @@ -324,7 +429,7 @@ public class GridBasicFeatures extends AbstractComponentTest { }, -1, c); for (int w = 50; w < 300; w += 50) { - createClickAction(w + "px", "Column" + c + " Width", + createClickAction(w + "px", "Column " + c + " Width", new Command() { @Override @@ -343,7 +448,7 @@ public class GridBasicFeatures extends AbstractComponentTest { } private static String getColumnProperty(int c) { - return "Column" + c; + return "Column " + c; } protected void createColumnGroupActions() { diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridKeyboardNavigationTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridKeyboardNavigationTest.java index 805213027e..e20b45bd1d 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridKeyboardNavigationTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridKeyboardNavigationTest.java @@ -104,7 +104,7 @@ public class GridKeyboardNavigationTest extends GridBasicFeaturesTest { public void testNavigationFromFooterToBody() { openTestURL(); - selectMenuPath("Component", "Footers", "Visible"); + selectMenuPath("Component", "Footer", "Visible"); GridElement grid = getGridElement(); grid.scrollToRow(300); @@ -146,7 +146,7 @@ public class GridKeyboardNavigationTest extends GridBasicFeaturesTest { public void testNavigateBetweenFooterAndBodyWithTab() { openTestURL(); - selectMenuPath("Component", "Footers", "Visible"); + selectMenuPath("Component", "Footer", "Visible"); GridElement grid = getGridElement(); grid.getCell(10, 2).click(); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingTest.java index 4a1d7b7be1..ee3f2a632b 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingTest.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; -import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.Keys; import org.openqa.selenium.interactions.Actions; @@ -30,11 +29,7 @@ import com.vaadin.tests.components.grid.GridElement; public class GridSortingTest extends GridBasicFeaturesTest { - /* - * TODO unignore once column header captions are reimplemented - */ @Test - @Ignore public void testProgrammaticSorting() throws IOException { openTestURL(); @@ -43,7 +38,7 @@ public class GridSortingTest extends GridBasicFeaturesTest { // Sorting by column 9 is sorting by row index that is represented as a // String. // First cells for first 3 rows are (9, 0), (99, 0) and (999, 0) - sortBy("Column9, DESC"); + sortBy("Column 9, DESC"); assertTrue("Column 9 should have the sort-desc stylename", grid .getHeaderCell(0, 9).getAttribute("class") @@ -53,12 +48,12 @@ public class GridSortingTest extends GridBasicFeaturesTest { for (int i = 0; i < 3; ++i) { row += "9"; assertEquals( - "Grid is not sorted by Column9 using descending direction.", + "Grid is not sorted by Column 9 using descending direction.", "(" + row + ", 0)", grid.getCell(i, 0).getText()); } // Column 10 is random numbers from Random with seed 13334 - sortBy("Column10, ASC"); + sortBy("Column 10, ASC"); assertFalse( "Column 9 should no longer have the sort-desc stylename", @@ -75,7 +70,7 @@ public class GridSortingTest extends GridBasicFeaturesTest { for (int i = 0; i < 5; ++i) { assertGreater( - "Grid is not sorted by Column10 using ascending direction", + "Grid is not sorted by Column 10 using ascending direction", Integer.parseInt(grid.getCell(i + 1, 10).getText()), Integer.parseInt(grid.getCell(i, 10).getText())); @@ -83,10 +78,10 @@ public class GridSortingTest extends GridBasicFeaturesTest { // Column 7 is row index as a number. Last three row are original rows // 2, 1 and 0. - sortBy("Column7, DESC"); + sortBy("Column 7, DESC"); for (int i = 0; i < 3; ++i) { assertEquals( - "Grid is not sorted by Column7 using descending direction", + "Grid is not sorted by Column 7 using descending direction", "(" + i + ", 0)", grid.getCell(GridBasicFeatures.ROWS - (i + 1), 0).getText()); } @@ -118,18 +113,18 @@ public class GridSortingTest extends GridBasicFeaturesTest { for (int i = 0; i < 3; ++i) { row += "9"; assertEquals( - "Grid is not sorted by Column9 using descending direction.", + "Grid is not sorted by Column 9 using descending direction.", "(" + row + ", 0)", grid.getCell(i, 0).getText()); } - assertEquals("2. Sort order: [Column9 ASCENDING]", getLogRow(2)); - assertEquals("4. Sort order: [Column9 DESCENDING]", getLogRow(0)); + assertEquals("2. Sort order: [Column 9 ASCENDING]", getLogRow(2)); + assertEquals("4. Sort order: [Column 9 DESCENDING]", getLogRow(0)); // Column 10 is random numbers from Random with seed 13334 // Click header to sort ascending grid.getHeaderCell(0, 10).click(); - assertEquals("6. Sort order: [Column10 ASCENDING]", getLogRow(0)); + assertEquals("6. Sort order: [Column 10 ASCENDING]", getLogRow(0)); // Not cleaning up correctly causes exceptions when scrolling. grid.scrollToRow(50); @@ -138,7 +133,7 @@ public class GridSortingTest extends GridBasicFeaturesTest { for (int i = 0; i < 5; ++i) { assertGreater( - "Grid is not sorted by Column10 using ascending direction", + "Grid is not sorted by Column 10 using ascending direction", Integer.parseInt(grid.getCell(i + 1, 10).getText()), Integer.parseInt(grid.getCell(i, 10).getText())); @@ -151,13 +146,13 @@ public class GridSortingTest extends GridBasicFeaturesTest { grid.getHeaderCell(0, 7).click(); for (int i = 0; i < 3; ++i) { assertEquals( - "Grid is not sorted by Column7 using descending direction", + "Grid is not sorted by Column 7 using descending direction", "(" + i + ", 0)", grid.getCell(GridBasicFeatures.ROWS - (i + 1), 0).getText()); } - assertEquals("9. Sort order: [Column7 ASCENDING]", getLogRow(3)); - assertEquals("11. Sort order: [Column7 DESCENDING]", getLogRow(1)); + assertEquals("9. Sort order: [Column 7 ASCENDING]", getLogRow(3)); + assertEquals("11. Sort order: [Column 7 DESCENDING]", getLogRow(1)); } @Test diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridStructureTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridStructureTest.java index 94f04e10a2..ced6963c32 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridStructureTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridStructureTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.assertTrue; import java.util.List; -import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; @@ -31,44 +30,36 @@ import com.vaadin.testbench.TestBenchElement; public class GridStructureTest extends GridBasicFeaturesTest { - /* - * TODO unignore once column header captions are reimplemented - */ @Test - @Ignore public void testHidingColumn() throws Exception { openTestURL(); // Column 0 should be visible List cells = getGridHeaderRowCells(); - assertEquals("Column0", cells.get(0).getText()); + assertEquals("Column 0", cells.get(0).getText()); // Hide column 0 - selectMenuPath("Component", "Columns", "Column0", "Visible"); + selectMenuPath("Component", "Columns", "Column 0", "Visible"); // Column 1 should now be the first cell cells = getGridHeaderRowCells(); - assertEquals("Column1", cells.get(0).getText()); + assertEquals("Column 1", cells.get(0).getText()); } - /* - * TODO unignore once column header captions are reimplemented - */ @Test - @Ignore public void testRemovingColumn() throws Exception { openTestURL(); // Column 0 should be visible List cells = getGridHeaderRowCells(); - assertEquals("Column0", cells.get(0).getText()); + assertEquals("Column 0", cells.get(0).getText()); // Hide column 0 - selectMenuPath("Component", "Columns", "Column0", "Remove"); + selectMenuPath("Component", "Columns", "Column 0", "Remove"); // Column 1 should now be the first cell cells = getGridHeaderRowCells(); - assertEquals("Column1", cells.get(0).getText()); + assertEquals("Column 1", cells.get(0).getText()); } @Test @@ -76,9 +67,9 @@ public class GridStructureTest extends GridBasicFeaturesTest { openTestURL(); // Remove columns 2,3,4 - selectMenuPath("Component", "Columns", "Column2", "Remove"); - selectMenuPath("Component", "Columns", "Column3", "Remove"); - selectMenuPath("Component", "Columns", "Column4", "Remove"); + selectMenuPath("Component", "Columns", "Column 2", "Remove"); + selectMenuPath("Component", "Columns", "Column 3", "Remove"); + selectMenuPath("Component", "Columns", "Column 4", "Remove"); // Scroll so new data is lazy loaded scrollGridVerticallyTo(1000); @@ -95,7 +86,7 @@ public class GridStructureTest extends GridBasicFeaturesTest { openTestURL(); // Freeze column 2 - selectMenuPath("Component", "Columns", "Column2", "Freeze"); + selectMenuPath("Component", "Columns", "Column 2", "Freeze"); WebElement cell = getBodyCellByRowAndColumn(0, 0); assertTrue(cell.getAttribute("class").contains("frozen")); @@ -127,20 +118,20 @@ public class GridStructureTest extends GridBasicFeaturesTest { assertEquals(100, cell.getSize().getWidth()); // Set first column to be 200px wide - selectMenuPath("Component", "Columns", "Column0", "Column0 Width", + selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", "200px"); cell = getBodyCellByRowAndColumn(0, 0); assertEquals(200, cell.getSize().getWidth()); // Set second column to be 150px wide - selectMenuPath("Component", "Columns", "Column1", "Column1 Width", + selectMenuPath("Component", "Columns", "Column 1", "Column 1 Width", "150px"); cell = getBodyCellByRowAndColumn(0, 1); assertEquals(150, cell.getSize().getWidth()); // Set first column to be auto sized (defaults to 100px currently) - selectMenuPath("Component", "Columns", "Column0", "Column0 Width", + selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", "Auto"); cell = getBodyCellByRowAndColumn(0, 0); @@ -203,7 +194,7 @@ public class GridStructureTest extends GridBasicFeaturesTest { selectMenuPath("Component", "Body rows", "Modify first row (getContainerProperty)"); assertEquals("(Second) modification with getItemProperty failed", - "modified: Column0", getBodyCellByRowAndColumn(0, 0).getText()); + "modified: Column 0", getBodyCellByRowAndColumn(0, 0).getText()); } private void assertPrimaryStylename(String stylename) { -- 2.39.5