From: Johannes Dahlström Date: Tue, 15 Jul 2014 11:36:01 +0000 (+0300) Subject: Start rewrite of client-side Grid header/footer API (#13334) X-Git-Tag: 7.4.0.beta1~9^2~189^2~54^2~59 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3626012f2ebf51c5433eb2671b5404e583a0f892;p=vaadin-framework.git Start rewrite of client-side Grid header/footer API (#13334) The old API is marked as deprecated and does not work anymore. Currently supported: * A single hard-coded header * Text captions TODO: * Footers * 0..n headers and footers * Column spanning * HTML content * Widget content * Component content * Sorting/Indicators * Server side API * Shared state handling Change-Id: I0448c36c8406807037b5e21e2db205a2ee24bc8a --- diff --git a/client/src/com/vaadin/client/ui/grid/ColumnGroup.java b/client/src/com/vaadin/client/ui/grid/ColumnGroup.java index 13468a0d8e..af83730ceb 100644 --- a/client/src/com/vaadin/client/ui/grid/ColumnGroup.java +++ b/client/src/com/vaadin/client/ui/grid/ColumnGroup.java @@ -34,6 +34,7 @@ import com.vaadin.client.ui.grid.renderers.TextRenderer; * @author Vaadin Ltd * @see ColumnGroupRow#addGroup(ColumnGroup...) */ +@Deprecated public class ColumnGroup { /** diff --git a/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java b/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java index 3c621fdd15..bae6a732e6 100644 --- a/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java +++ b/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java @@ -33,6 +33,7 @@ import java.util.Set; * @since * @author Vaadin Ltd */ +@Deprecated public class ColumnGroupRow { /** diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java index 471f62cdeb..539c18f8c8 100644 --- a/client/src/com/vaadin/client/ui/grid/Grid.java +++ b/client/src/com/vaadin/client/ui/grid/Grid.java @@ -192,6 +192,8 @@ public class Grid extends Composite implements */ private Escalator escalator = GWT.create(Escalator.class); + private GridHeader header = GWT.create(GridHeader.class); + /** * List of columns in the grid. Order defines the visible order. */ @@ -206,16 +208,19 @@ public class Grid extends Composite implements /** * The column groups rows added to the grid */ + @Deprecated private final List> columnGroupRows = new ArrayList>(); /** * Are the headers for the columns visible */ + @Deprecated private boolean columnHeadersVisible = true; /** * Are the footers for the columns visible */ + @Deprecated private boolean columnFootersVisible = false; /** @@ -574,11 +579,13 @@ public class Grid extends Composite implements /** * The text displayed in the header of the column */ + @Deprecated private String header; /** * Text displayed in the column footer */ + @Deprecated private String footer; /** @@ -594,12 +601,14 @@ public class Grid extends Composite implements /** * Renderer for rendering the header cell value into the cell */ + @Deprecated private Renderer headerRenderer = new SortableColumnHeaderRenderer( new TextRenderer()); /** * Renderer for rendering the footer cell value into the cell */ + @Deprecated private Renderer footerRenderer = new TextRenderer(); private boolean sortable = false; @@ -661,6 +670,7 @@ public class Grid extends Composite implements * * @return the text displayed in the column caption */ + @Deprecated public String getHeaderCaption() { return header; } @@ -670,6 +680,7 @@ public class Grid extends Composite implements * * @return a renderer that renders header cells */ + @Deprecated public Renderer getHeaderRenderer() { return headerRenderer; } @@ -680,6 +691,7 @@ public class Grid extends Composite implements * @param renderer * The renderer to use for rendering header cells. */ + @Deprecated public void setHeaderRenderer(Renderer renderer) { if (renderer == null) { throw new IllegalArgumentException("Renderer cannot be null."); @@ -695,6 +707,7 @@ public class Grid extends Composite implements * * @return a renderer that renders footer cells */ + @Deprecated public Renderer getFooterRenderer() { return footerRenderer; } @@ -705,6 +718,7 @@ public class Grid extends Composite implements * @param renderer * The renderer to use for rendering footer cells. */ + @Deprecated public void setFooterRenderer(Renderer renderer) { if (renderer == null) { throw new IllegalArgumentException("Renderer cannot be null."); @@ -721,6 +735,7 @@ public class Grid extends Composite implements * @param caption * the text displayed in the column header */ + @Deprecated public void setHeaderCaption(String caption) { if (SharedUtil.equals(caption, header)) { return; @@ -739,6 +754,7 @@ public class Grid extends Composite implements * * @return The text displayed in the footer of the column */ + @Deprecated public String getFooterCaption() { return footer; } @@ -749,6 +765,7 @@ public class Grid extends Composite implements * @param caption * the text displayed in the footer of the column */ + @Deprecated public void setFooterCaption(String caption) { if (SharedUtil.equals(caption, footer)) { return; @@ -898,6 +915,7 @@ public class Grid extends Composite implements /** * Base class for header / footer escalator updater */ + @Deprecated protected abstract class HeaderFooterEscalatorUpdater implements EscalatorUpdater { @@ -1125,36 +1143,44 @@ public class Grid extends Composite implements * @return the updater that updates the data in the escalator. */ private EscalatorUpdater createHeaderUpdater() { - return new HeaderFooterEscalatorUpdater(escalator.getHeader(), true) { + return new EscalatorUpdater() { @Override - public boolean isRowVisible(ColumnGroupRow row) { - return row.isHeaderVisible(); - } + public void update(Row row, Iterable cellsToUpdate) { + GridHeader.HeaderRow headerRow = header.getRow(row.getRow()); - @Override - public String getGroupValue(ColumnGroup group) { - return group.getHeaderCaption(); + int colIndex = -1; + for (FlyweightCell cell : cellsToUpdate) { + if (colIndex == -1) { + colIndex = cell.getColumn(); + } + while (!columns.get(colIndex).isVisible()) { + colIndex++; + } + + headerRow.getRenderer().render(cell, + headerRow.getCell(colIndex).getText()); + + colIndex++; + } } @Override - public String getColumnValue(GridColumn column) { - return column.getHeaderCaption(); + public void preAttach(Row row, Iterable cellsToAttach) { } @Override - public boolean firstRowIsVisible() { - return isColumnHeadersVisible(); + public void postAttach(Row row, + Iterable attachedCells) { } @Override - public Renderer getRenderer(GridColumn column) { - return column.getHeaderRenderer(); + public void preDetach(Row row, Iterable cellsToDetach) { } @Override - public Renderer getGroupRenderer(ColumnGroup group) { - return group.getHeaderRenderer(); + public void postDetach(Row row, + Iterable detachedCells) { } }; } @@ -1306,38 +1332,7 @@ public class Grid extends Composite implements * @return the updater that updates the data in the escalator. */ private EscalatorUpdater createFooterUpdater() { - return new HeaderFooterEscalatorUpdater(escalator.getFooter(), false) { - - @Override - public boolean isRowVisible(ColumnGroupRow row) { - return row.isFooterVisible(); - } - - @Override - public String getGroupValue(ColumnGroup group) { - return group.getFooterCaption(); - } - - @Override - public String getColumnValue(GridColumn column) { - return column.getFooterCaption(); - } - - @Override - public boolean firstRowIsVisible() { - return isColumnFootersVisible(); - } - - @Override - public Renderer getRenderer(GridColumn column) { - return column.getFooterRenderer(); - } - - @Override - public Renderer getGroupRenderer(ColumnGroup group) { - return group.getFooterRenderer(); - } - }; + return EscalatorUpdater.NULL; } /** @@ -1437,6 +1432,8 @@ public class Grid extends Composite implements // Register column with grid columns.add(index, column); + header.addColumn(column, index); + // Register this grid instance with the column ((AbstractGridColumn) column).setGrid(this); @@ -1537,6 +1534,7 @@ public class Grid extends Composite implements int columnIndex = columns.indexOf(column); int visibleIndex = findVisibleColumnIndex(column); columns.remove(columnIndex); + header.removeColumn(columnIndex); // de-register column with grid ((AbstractGridColumn) column).setGrid(null); @@ -1618,6 +1616,7 @@ public class Grid extends Composite implements * @param visible * true if header rows should be visible */ + @Deprecated public void setColumnHeadersVisible(boolean visible) { if (visible == isColumnHeadersVisible()) { return; @@ -1631,6 +1630,7 @@ public class Grid extends Composite implements * * @return true if they are visible */ + @Deprecated public boolean isColumnHeadersVisible() { return columnHeadersVisible; } @@ -1664,6 +1664,7 @@ public class Grid extends Composite implements * @param visible * true if the footer row should be visible */ + @Deprecated public void setColumnFootersVisible(boolean visible) { if (visible == isColumnFootersVisible()) { return; @@ -1678,6 +1679,7 @@ public class Grid extends Composite implements * @return true if they are visible * */ + @Deprecated public boolean isColumnFootersVisible() { return columnFootersVisible; } @@ -1709,6 +1711,7 @@ public class Grid extends Composite implements * * @return a column group row instance you can use to add column groups */ + @Deprecated public ColumnGroupRow addColumnGroupRow() { ColumnGroupRow row = new ColumnGroupRow(this); columnGroupRows.add(row); @@ -1727,6 +1730,7 @@ public class Grid extends Composite implements * the index where the column group row should be added * @return a column group row instance you can use to add column groups */ + @Deprecated public ColumnGroupRow addColumnGroupRow(int rowIndex) { ColumnGroupRow row = new ColumnGroupRow(this); columnGroupRows.add(rowIndex, row); @@ -1741,6 +1745,7 @@ public class Grid extends Composite implements * @param row * The row to remove */ + @Deprecated public void removeColumnGroupRow(ColumnGroupRow row) { columnGroupRows.remove(row); refreshHeader(); @@ -1753,6 +1758,7 @@ public class Grid extends Composite implements * @return a unmodifiable list of column group rows * */ + @Deprecated public List> getColumnGroupRows() { return Collections.unmodifiableList(new ArrayList>( columnGroupRows)); @@ -1768,6 +1774,7 @@ public class Grid extends Composite implements * @return A column group for the row and column or null if not * found. */ + @Deprecated private ColumnGroup getGroupForColumn(ColumnGroupRow row, GridColumn column) { for (ColumnGroup group : row.getGroups()) { diff --git a/client/src/com/vaadin/client/ui/grid/GridHeader.java b/client/src/com/vaadin/client/ui/grid/GridHeader.java new file mode 100644 index 0000000000..023973c511 --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/GridHeader.java @@ -0,0 +1,105 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.vaadin.client.ui.grid.renderers.TextRenderer; + +/** + * Represents the header section of a Grid. A header consists of a single header + * row containing a header cell for each column. Each cell has a simple textual + * caption. + * + * TODO Arbitrary number of header rows (zero included) + * + * TODO Merging header cells + * + * TODO "Default" row with sorting + * + * TODO Widgets in cells + * + * TODO HTML in cells + * + * @since + * @author Vaadin Ltd + */ +public class GridHeader { + + /** + * A single row in a grid header section. + * + * @since + * @author Vaadin Ltd + */ + public static class HeaderRow { + + private List cells = new ArrayList(); + + private Renderer renderer = new TextRenderer(); + + public HeaderCell getCell(int index) { + return cells.get(index); + } + + protected void addCell(int index) { + cells.add(index, new HeaderCell()); + } + + protected void removeCell(int index) { + cells.remove(index); + } + + protected Renderer getRenderer() { + return renderer; + } + } + + /** + * A single cell in a grid header row. Has a textual caption. + * + * @since + * @author Vaadin Ltd + */ + public static class HeaderCell { + + private String text = ""; + + public void setText(String text) { + this.text = text; + } + + public String getText() { + return text; + } + } + + private List rows = Arrays.asList(new HeaderRow()); + + public HeaderRow getRow(int index) { + return rows.get(index); + } + + protected void addColumn(GridColumn column, int index) { + getRow(0).addCell(index); + } + + protected void removeColumn(int index) { + getRow(0).removeCell(index); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java index 10d2c8592a..2e062f36c6 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java @@ -18,6 +18,7 @@ package com.vaadin.tests.components.grid; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; +import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; @@ -28,7 +29,11 @@ import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") public class GridSingleColumnTest extends MultiBrowserTest { + /* + * TODO unignore once column header captions are reimplemented + */ @Test + @Ignore public void headerIsVisible() { openTestURL(); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java index 79501f50ac..a3c62e0303 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java @@ -15,12 +15,16 @@ */ package com.vaadin.tests.components.grid.basicfeatures; +import java.util.ArrayList; +import java.util.List; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; +import com.vaadin.testbench.TestBenchElement; import com.vaadin.tests.annotations.TestCategory; import com.vaadin.tests.components.grid.GridElement; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -59,6 +63,14 @@ public abstract class GridBasicFeaturesTest extends MultiBrowserTest { getGridVerticalScrollbar()); } + protected List getGridHeaderRowCells() { + List headerCells = new ArrayList(); + for (int i = 0; i < getGridElement().getHeaderCount(); ++i) { + headerCells.addAll(getGridElement().getHeaderCells(i)); + } + return headerCells; + } + private Object executeScript(String script, WebElement element) { final WebDriver driver = getDriver(); if (driver instanceof JavascriptExecutor) { diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeaderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeaderTest.java new file mode 100644 index 0000000000..dfbb1679b0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeaderTest.java @@ -0,0 +1,36 @@ +/* + * 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.tests.components.grid.basicfeatures; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.TestBenchElement; + +public class GridHeaderTest extends GridBasicClientFeaturesTest { + + @Test + public void testHeaderVisible() throws Exception { + openTestURL(); + + // Column headers should be visible + List cells = getGridHeaderRowCells(); + assertEquals(GridBasicFeatures.COLUMNS, cells.size()); + } +} 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 820070f933..f706c1791d 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingTest.java @@ -21,13 +21,18 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; +import org.junit.Ignore; import org.junit.Test; 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(); 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 17438fd4bb..94f04e10a2 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridStructureTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridStructureTest.java @@ -20,117 +20,22 @@ import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.ArrayList; import java.util.List; +import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import com.vaadin.testbench.TestBenchElement; -import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; -import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; public class GridStructureTest extends GridBasicFeaturesTest { + /* + * TODO unignore once column header captions are reimplemented + */ @Test - public void testColumnHeaderCaptions() throws Exception { - openTestURL(); - - // Column headers should be visible - List cells = getGridHeaderRowCells(); - assertEquals(GridBasicFeatures.COLUMNS, cells.size()); - assertEquals("Column0", cells.get(0).getText()); - assertEquals("Column1", cells.get(1).getText()); - assertEquals("Column2", cells.get(2).getText()); - } - - @Test - public void testColumnFooterCaptions() throws Exception { - openTestURL(); - - // footer row should by default be hidden - List cells = getGridFooterRowCells(); - assertEquals(0, cells.size()); - - // Open footer row - selectMenuPath("Component", "Footers", "Visible"); - - // Footers should now be visible - cells = getGridFooterRowCells(); - assertEquals(GridBasicFeatures.COLUMNS, cells.size()); - assertEquals("Footer 0", cells.get(0).getText()); - assertEquals("Footer 1", cells.get(1).getText()); - assertEquals("Footer 2", cells.get(2).getText()); - } - - @Test - public void testColumnGroupHeaders() throws Exception { - openTestURL(); - - // Hide column headers for this test - selectMenuPath("Component", "Headers", "Visible"); - - List cells = getGridHeaderRowCells(); - - // header row should be empty - assertEquals(0, cells.size()); - - // add a group row - selectMenuPath("Component", "Column groups", "Add group row"); - - // Empty group row cells should be present - cells = getGridHeaderRowCells(); - assertEquals(GridBasicFeatures.COLUMNS, cells.size()); - - // Group columns 0 & 1 - selectMenuPath("Component", "Column groups", "Column group row 1", - "Group Column 0 & 1"); - - cells = getGridHeaderRowCells(); - assertEquals("Column 0 & 1", cells.get(0).getText()); - } - - @Test - public void testColumnGroupFooters() throws Exception { - openTestURL(); - - // add a group row - selectMenuPath("Component", "Column groups", "Add group row"); - - // Set footer visible - selectMenuPath("Component", "Column groups", "Column group row 1", - "Footer Visible"); - - // Group columns 0 & 1 - selectMenuPath("Component", "Column groups", "Column group row 1", - "Group Column 0 & 1"); - - List cells = getGridFooterRowCells(); - assertEquals("Column 0 & 1", cells.get(0).getText()); - } - - @Test - public void testGroupingSameColumnsOnRowThrowsException() throws Exception { - openTestURL(); - - // add a group row - selectMenuPath("Component", "Column groups", "Add group row"); - - // Group columns 0 & 1 - selectMenuPath("Component", "Column groups", "Column group row 1", - "Group Column 0 & 1"); - - // Group columns 1 & 2 shoud fail - selectMenuPath("Component", "Column groups", "Column group row 1", - "Group Column 1 & 2"); - - assertTrue(getLogRow(0) - .contains( - "Exception occured, java.lang.IllegalArgumentExceptionColumn Column1 already belongs to another group.")); - } - - @Test + @Ignore public void testHidingColumn() throws Exception { openTestURL(); @@ -146,7 +51,11 @@ public class GridStructureTest extends GridBasicFeaturesTest { assertEquals("Column1", cells.get(0).getText()); } + /* + * TODO unignore once column header captions are reimplemented + */ @Test + @Ignore public void testRemovingColumn() throws Exception { openTestURL(); @@ -328,20 +237,4 @@ public class GridStructureTest extends GridBasicFeaturesTest { private WebElement getTableWrapper() { return getGridElement().findElement(By.xpath("./div[3]")); } - - private List getGridHeaderRowCells() { - List headerCells = new ArrayList(); - for (int i = 0; i < getGridElement().getHeaderCount(); ++i) { - headerCells.addAll(getGridElement().getHeaderCells(i)); - } - return headerCells; - } - - private List getGridFooterRowCells() { - List footerCells = new ArrayList(); - for (int i = 0; i < getGridElement().getFooterCount(); ++i) { - footerCells.addAll(getGridElement().getFooterCells(i)); - } - return footerCells; - } }