aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJohannes Dahlström <johannesd@vaadin.com>2016-09-26 18:45:28 +0300
committerJohannes Dahlström <johannesd@vaadin.com>2016-09-28 00:44:10 +0300
commit96119ab0224421d69393d9d41ed02900121a683e (patch)
treeadc27cf326fdf007c24db9a742f2f41f2637fc94 /server
parent680b7009d4f453dc8eec42975192094b2e0e8e2f (diff)
downloadvaadin-framework-96119ab0224421d69393d9d41ed02900121a683e.tar.gz
vaadin-framework-96119ab0224421d69393d9d41ed02900121a683e.zip
Implement default header row in new Grid
Change-Id: Id26a98caca022ed2a4dbe0128a79721a54f5b267
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/ui/Grid.java99
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/Header.java80
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java87
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java36
5 files changed, 287 insertions, 49 deletions
diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java
index 3777decbe9..b1a2c64ec8 100644
--- a/server/src/main/java/com/vaadin/ui/Grid.java
+++ b/server/src/main/java/com/vaadin/ui/Grid.java
@@ -51,6 +51,7 @@ import com.vaadin.shared.ui.grid.GridState;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.shared.ui.grid.SectionState;
import com.vaadin.ui.components.grid.Header;
+import com.vaadin.ui.components.grid.Header.Row;
import com.vaadin.ui.renderers.AbstractRenderer;
import com.vaadin.ui.renderers.Renderer;
import com.vaadin.ui.renderers.TextRenderer;
@@ -873,13 +874,19 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
* Sets the header caption for this column.
*
* @param caption
- * the header caption
+ * the header caption, not null
*
* @return this column
*/
public Column<T, V> setCaption(String caption) {
Objects.requireNonNull(caption, "Header caption can't be null");
getState().caption = caption;
+
+ HeaderRow row = getParent().getDefaultHeaderRow();
+ if (row != null) {
+ row.getCell(getId()).setText(caption);
+ }
+
return this;
}
@@ -1428,8 +1435,10 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
* Returns the cell on this row corresponding to the given column id.
*
* @param columnId
- * the id of the column whose header cell to get
+ * the id of the column whose header cell to get, not null
* @return the header cell
+ * @throws IllegalArgumentException
+ * if there is no such column in the grid
*/
public HeaderCell getCell(String columnId);
@@ -1437,8 +1446,10 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
* Returns the cell on this row corresponding to the given column.
*
* @param column
- * the column whose header cell to get
+ * the column whose header cell to get, not null
* @return the header cell
+ * @throws IllegalArgumentException
+ * if there is no such column in the grid
*/
public default HeaderCell getCell(Column<?, ?> column) {
return getCell(column.getId());
@@ -1461,11 +1472,24 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
* Sets the textual caption of this cell.
*
* @param text
- * the header caption to set
+ * the header caption to set, not null
*/
public void setText(String text);
}
+ private class HeaderImpl extends Header {
+
+ @Override
+ protected SectionState getState(boolean markAsDirty) {
+ return Grid.this.getState(markAsDirty).header;
+ }
+
+ @Override
+ protected Collection<Column<T, ?>> getColumns() {
+ return Grid.this.getColumns();
+ }
+ };
+
private KeyMapper<Column<T, ?>> columnKeys = new KeyMapper<>();
private Set<Column<T, ?>> columnSet = new LinkedHashSet<>();
private List<SortOrder<Column<T, ?>>> sortOrder = new ArrayList<>();
@@ -1474,12 +1498,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
private StyleGenerator<T> styleGenerator = item -> null;
private DescriptionGenerator<T> descriptionGenerator;
- private Header header = new Header() {
- @Override
- protected SectionState getState(boolean markAsDirty) {
- return Grid.this.getState(markAsDirty).header;
- }
- };
+ private Header header = new HeaderImpl();
/**
* Constructor for the {@link Grid} component.
@@ -1488,7 +1507,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
setSelectionModel(new SingleSelection());
registerRpc(new GridServerRpcImpl());
- appendHeaderRow();
+ setDefaultHeaderRow(appendHeaderRow());
detailsManager = new DetailsManager<>();
addExtension(detailsManager);
@@ -1545,10 +1564,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
getHeader().addColumn(columnId);
- if (getHeaderRowCount() > 0) {
- // TODO Default header API to be added in a later patch
- HeaderRow defaultHeader = getHeaderRow(0);
- defaultHeader.getCell(columnId).setText(caption);
+ if (getDefaultHeaderRow() != null) {
+ getDefaultHeaderRow().getCell(columnId).setText(caption);
}
return column;
@@ -1580,7 +1597,9 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
if (columnSet.remove(column)) {
columnKeys.remove(column);
removeDataGenerator(column);
+ getHeader().removeColumn(column.getId());
column.remove();
+
}
}
@@ -1846,14 +1865,14 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
/**
* Returns the header row at the given index.
*
- * @param rowIndex
+ * @param index
* the index of the row, where the topmost row has index zero
* @return the header row at the index
* @throws IndexOutOfBoundsException
* if {@code rowIndex < 0 || rowIndex >= getHeaderRowCount()}
*/
- public HeaderRow getHeaderRow(int rowIndex) {
- return getHeader().getRow(rowIndex);
+ public HeaderRow getHeaderRow(int index) {
+ return getHeader().getRow(index);
}
/**
@@ -1917,7 +1936,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
}
/**
- * Removes the given row from the header section.
+ * Removes the given row from the header section. Removing a default row
+ * sets the Grid to have no default row.
*
* @param row
* the header row to be removed, not null
@@ -1937,25 +1957,54 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
/**
* Removes the row at the given position from the header section.
*
- * @param rowIndex
+ * @param index
* the index of the row to remove, where the topmost row has
* index zero
*
* @throws IndexOutOfBoundsException
- * if {@code rowIndex < 0 || rowIndex >= getHeaderRowCount()}
+ * if {@code index < 0 || index >= getHeaderRowCount()}
*
* @see #removeHeaderRow(HeaderRow)
* @see #addHeaderRowAt(int)
* @see #appendHeaderRow()
* @see #prependHeaderRow()
*/
- public void removeHeaderRow(int rowIndex) {
- getHeader().removeRow(rowIndex);
+ public void removeHeaderRow(int index) {
+ getHeader().removeRow(index);
+ }
+
+ /**
+ * Returns the current default row of the header.
+ *
+ * @return the default row or null if no default row set
+ *
+ * @see #setDefaultHeaderRow(HeaderRow)
+ */
+ public HeaderRow getDefaultHeaderRow() {
+ return header.getDefaultRow();
+ }
+
+ /**
+ * Sets the default row of the header. The default row is a special header
+ * row that displays column captions and sort indicators. By default Grid
+ * has a single row which is also the default row. When a header row is set
+ * as the default row, any existing cell content is replaced by the column
+ * captions.
+ *
+ * @param row
+ * the new default row, or null for no default row
+ *
+ * @throws IllegalArgumentException
+ * if the header does not contain the row
+ */
+ public void setDefaultHeaderRow(HeaderRow row) {
+ header.setDefaultRow((Row) row);
}
/**
* Returns the header section of this grid. The default header contains a
- * single row displaying the column captions.
+ * single row, set as the {@linkplain #setDefaultHeaderRow(HeaderRow)
+ * default row}.
*
* @return the header section
*/
@@ -1994,7 +2043,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
}
/**
- * Registers a new column visibility change listener
+ * Registers a new column visibility change listener.
*
* @param listener
* the listener to register, not null
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/Header.java b/server/src/main/java/com/vaadin/ui/components/grid/Header.java
index 8348795c10..31f80a9add 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/Header.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/Header.java
@@ -19,21 +19,34 @@ import com.vaadin.ui.Grid;
/**
* Represents the header section of a Grid.
+ *
+ * @author Vaadin Ltd.
+ *
+ * @since 8.0
*/
public abstract class Header extends StaticSection<Header.Row> {
+ /**
+ * A row in a Grid header.
+ */
public class Row extends StaticSection.StaticRow<Row.Cell>
implements Grid.HeaderRow {
+ /**
+ * A cell in a Grid header row.
+ */
public class Cell extends StaticSection.StaticCell implements
Grid.HeaderCell {
+ /**
+ * Creates a new header cell.
+ */
protected Cell() {
super(Row.this);
}
}
/**
- * @param section
+ * Creates a new header row.
*/
protected Row() {
super(Header.this);
@@ -48,10 +61,75 @@ public abstract class Header extends StaticSection<Header.Row> {
protected String getCellTagName() {
return "th";
}
+
+ /**
+ * Returns whether this row is the default header row.
+ *
+ * @return {@code true} if this row is the default row, {@code false}
+ * otherwise.
+ */
+ protected boolean isDefault() {
+ return getRowState().defaultHeader;
+ }
+
+ /**
+ * Sets whether this row is the default header row.
+ *
+ * @param defaultHeader
+ * {@code true} to set to default, {@code false} otherwise.
+ */
+ protected void setDefault(boolean defaultHeader) {
+ getRowState().defaultHeader = defaultHeader;
+ }
}
@Override
public Row createRow() {
return new Row();
}
+
+ @Override
+ public void removeRow(int index) {
+ if (getRow(index).isDefault()) {
+ setDefaultRow(null);
+ }
+ super.removeRow(index);
+ }
+
+ /**
+ * Returns the default row of this header. The default row displays column
+ * captions and sort indicators.
+ *
+ * @return the default row, or {@code null} if there is no default row
+ */
+ public Row getDefaultRow() {
+ return getRows().stream()
+ .filter(Row::isDefault)
+ .findAny().orElse(null);
+ }
+
+ /**
+ * Sets the default row of this header. The default row displays column
+ * captions and sort indicators.
+ *
+ * @param defaultRow
+ * the new default row, or null for no default row
+ *
+ * @throws IllegalArgumentException
+ * if the header does not contain the row
+ */
+ public void setDefaultRow(Row defaultRow) {
+ if (defaultRow != null) {
+ if (!getRows().contains(defaultRow)) {
+ throw new IllegalArgumentException(
+ "The section does not contain the row");
+ }
+ if (defaultRow.isDefault()) {
+ return;
+ }
+ }
+ getRows().forEach(row -> row.setDefault(row == defaultRow));
+
+ markAsDirty();
+ }
}
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java b/server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java
index dbd5749bd0..e1c64f31e6 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java
@@ -17,6 +17,8 @@ package com.vaadin.ui.components.grid;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -25,6 +27,7 @@ import java.util.Objects;
import com.vaadin.shared.ui.grid.SectionState;
import com.vaadin.shared.ui.grid.SectionState.CellState;
import com.vaadin.shared.ui.grid.SectionState.RowState;
+import com.vaadin.ui.Grid.Column;
/**
* Represents the header or footer section of a Grid.
@@ -48,9 +51,9 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
public abstract static class StaticRow<CELL extends StaticCell>
implements Serializable {
- private RowState rowState = new RowState();
- private StaticSection<?> section;
- private Map<Object, CELL> cells = new LinkedHashMap<>();
+ private final RowState rowState = new RowState();
+ private final StaticSection<?> section;
+ private final Map<Object, CELL> cells = new LinkedHashMap<>();
/**
* Creates a new row belonging to the given section.
@@ -118,10 +121,17 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
*
* @param columnId
* the id of the column
- * @return the cell for the given column or null if not found
+ * @return the cell for the given column
+ *
+ * @throws IllegalArgumentException
+ * if no cell was found for the column id
*/
public CELL getCell(String columnId) {
CELL cell = cells.get(columnId);
+ if (cell == null) {
+ throw new IllegalArgumentException(
+ "No cell found for column id " + columnId);
+ }
return cell;
}
}
@@ -186,7 +196,7 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
}
}
- private List<ROW> rows = new ArrayList<>();
+ private final List<ROW> rows = new ArrayList<>();
/**
* Creates a new row instance.
@@ -205,6 +215,8 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
*/
protected abstract SectionState getState(boolean markAsDirty);
+ protected abstract Collection<? extends Column<?, ?>> getColumns();
+
/**
* Marks the state of this section as modified.
*/
@@ -225,6 +237,9 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
ROW row = createRow();
rows.add(index, row);
getState(true).rows.add(index, row.getRowState());
+
+ getColumns().stream().forEach(column -> row.addCell(column.getId()));
+
return row;
}
@@ -304,4 +319,13 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
row.removeCell(columnId);
}
}
+
+ /**
+ * Returns an unmodifiable list of the rows in this section.
+ *
+ * @return the rows in this section
+ */
+ protected List<ROW> getRows() {
+ return Collections.unmodifiableList(rows);
+ }
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java
new file mode 100644
index 0000000000..80984cc647
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.grid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.function.Function;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.HeaderRow;
+
+public class GridDefaultHeaderTest {
+ private Grid<String> grid;
+ private Column<?, ?> column1, column2;
+
+ @Before
+ public void setUp() {
+ grid = new Grid<>();
+
+ column1 = grid.addColumn("First", Function.identity());
+ column2 = grid.addColumn("Second", Function.identity());
+ }
+
+ @Test
+ public void initialState_hasDefaultHeader() {
+ HeaderRow defaultHeader = grid.getDefaultHeaderRow();
+
+ assertEquals(1, grid.getHeaderRowCount());
+ assertSame(grid.getHeaderRow(0), defaultHeader);
+ assertEquals("First", defaultHeader.getCell(column1).getText());
+ assertEquals("Second", defaultHeader.getCell(column2).getText());
+ }
+
+ @Test
+ public void initialState_defaultHeaderRemovable() {
+ grid.removeHeaderRow(0);
+
+ assertEquals(0, grid.getHeaderRowCount());
+ assertNull(grid.getDefaultHeaderRow());
+ }
+
+ @Test
+ public void initialState_updateColumnCaption_defaultHeaderUpdated() {
+ column1.setCaption("1st");
+
+ assertEquals("1st", grid.getDefaultHeaderRow().getCell(column1)
+ .getText());
+ }
+
+ @Test
+ public void customDefaultHeader_updateColumnCaption_defaultHeaderUpdated() {
+ grid.setDefaultHeaderRow(grid.appendHeaderRow());
+ column1.setCaption("1st");
+
+ assertEquals("1st", grid.getDefaultHeaderRow().getCell(column1)
+ .getText());
+ assertEquals("First", grid.getHeaderRow(0).getCell(column1).getText());
+ }
+
+ @Test
+ public void noDefaultRow_updateColumnCaption_headerNotUpdated() {
+ grid.setDefaultHeaderRow(null);
+ column1.setCaption("1st");
+
+ assertEquals("First", grid.getHeaderRow(0).getCell(column1)
+ .getText());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java
index 87c2632b40..a566ae3685 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java
@@ -16,9 +16,12 @@
package com.vaadin.tests.server.component.grid;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
+import java.util.function.Function;
+
import org.junit.Before;
import org.junit.Test;
@@ -29,28 +32,10 @@ import com.vaadin.ui.Grid.HeaderRow;
public class GridHeaderFooterTest {
private Grid<String> grid;
- private Column<?, ?> column1, column2;
@Before
public void setUp() {
grid = new Grid<>();
-
- column1 = grid.addColumn("First", s -> s.substring(0, 1));
- column2 = grid.addColumn("Rest", s -> s.substring(1));
- }
-
- @Test
- public void initialState_hasDefaultHeader() {
- assertEquals(1, grid.getHeaderRowCount());
- HeaderRow defaultHeader = grid.getHeaderRow(0);
- assertEquals("First", defaultHeader.getCell(column1).getText());
- assertEquals("Rest", defaultHeader.getCell(column2).getText());
- }
-
- @Test
- public void initialState_defaultHeaderRemovable() {
- grid.removeHeaderRow(0);
- assertEquals(0, grid.getHeaderRowCount());
}
@Test
@@ -152,4 +137,19 @@ public class GridHeaderFooterTest {
}
grid.removeHeaderRow(row);
}
+
+ @Test
+ public void addColumn_headerCellAdded() {
+ Column<?, ?> column = grid.addColumn("Col", Function.identity());
+
+ assertNotNull(grid.getHeaderRow(0).getCell(column));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void removeColumn_headerCellRemoved() {
+ Column<String, ?> column = grid.addColumn("Col", Function.identity());
+ grid.removeColumn(column);
+
+ grid.getHeaderRow(0).getCell(column);
+ }
}