diff options
author | John Ahlroos <john@vaadin.com> | 2014-06-05 09:53:44 +0300 |
---|---|---|
committer | John Ahlroos <john@vaadin.com> | 2014-06-17 10:53:46 +0300 |
commit | c53db1fe7ee2c6993dcb38574fdeed1391658cd9 (patch) | |
tree | e781feb3f84511e43907318b7d1c61fe6220149b | |
parent | 327399e9abeaae43f83919246c3df33a33ed6161 (diff) | |
download | vaadin-framework-c53db1fe7ee2c6993dcb38574fdeed1391658cd9.tar.gz vaadin-framework-c53db1fe7ee2c6993dcb38574fdeed1391658cd9.zip |
Call ComplexRenderer.setContentVisible() from Grid body updater #13334
Change-Id: Icba9d9f3e5cdc6412c9c004356c33304024be33b
5 files changed, 320 insertions, 109 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java index ceaa63c9b6..ca3c272491 100644 --- a/client/src/com/vaadin/client/ui/grid/Grid.java +++ b/client/src/com/vaadin/client/ui/grid/Grid.java @@ -58,7 +58,7 @@ import com.vaadin.shared.util.SharedUtil; /** * A data grid view that supports columns and lazy loading of data rows from a * data source. - * + * * <h3>Columns</h3> * <p> * The {@link GridColumn} class defines the renderer used to render a cell in @@ -72,15 +72,15 @@ import com.vaadin.shared.util.SharedUtil; * specific column index using {@link Grid#getColumn(int)}. * </p> * <p> - * + * * TODO Explain about headers/footers once the multiple header/footer api has * been implemented - * + * * <h3>Data sources</h3> * <p> * TODO Explain about what a data source is and how it should be implemented. * </p> - * + * * @param <T> * The row type of the grid. The row type is the POJO type from where * the data is retrieved into the column cells. @@ -217,6 +217,9 @@ public class Grid<T> extends Composite implements private SelectionColumn selectionColumn; + private String rowHasDataStyleName; + private String rowSelectedStyleName; + /** * Current selection model. */ @@ -266,10 +269,10 @@ public class Grid<T> extends Composite implements /** * Base class for grid columns internally used by the Grid. The user should * use {@link GridColumn} when creating new columns. - * + * * @param <C> * the column type - * + * * @param <T> * the row type */ @@ -317,7 +320,7 @@ public class Grid<T> extends Composite implements /** * Constructs a new column with a custom renderer. - * + * * @param renderer * The renderer to use for rendering the cells */ @@ -331,7 +334,7 @@ public class Grid<T> extends Composite implements /** * Constructs a new column with custom renderers for rows, header and * footer cells. - * + * * @param bodyRenderer * The renderer to use for rendering body cells * @param headerRenderer @@ -352,7 +355,7 @@ public class Grid<T> extends Composite implements /** * Internally used by the grid to set itself - * + * * @param grid */ private void setGrid(Grid<T> grid) { @@ -375,7 +378,7 @@ public class Grid<T> extends Composite implements /** * Gets text in the header of the column. By default the header caption * is empty. - * + * * @return the text displayed in the column caption */ public String getHeaderCaption() { @@ -384,7 +387,7 @@ public class Grid<T> extends Composite implements /** * Returns the renderer used for rendering the header cells - * + * * @return a renderer that renders header cells */ public Renderer<String> getHeaderRenderer() { @@ -393,7 +396,7 @@ public class Grid<T> extends Composite implements /** * Sets the renderer that renders header cells. Should not be null. - * + * * @param renderer * The renderer to use for rendering header cells. */ @@ -409,7 +412,7 @@ public class Grid<T> extends Composite implements /** * Returns the renderer used for rendering the footer cells - * + * * @return a renderer that renders footer cells */ public Renderer<String> getFooterRenderer() { @@ -418,7 +421,7 @@ public class Grid<T> extends Composite implements /** * Sets the renderer that renders footer cells. Should not be null. - * + * * @param renderer * The renderer to use for rendering footer cells. */ @@ -434,7 +437,7 @@ public class Grid<T> extends Composite implements /** * Sets the text in the header of the column. - * + * * @param caption * the text displayed in the column header */ @@ -453,7 +456,7 @@ public class Grid<T> extends Composite implements /** * Gets text in the footer of the column. By default the footer caption * is empty. - * + * * @return The text displayed in the footer of the column */ public String getFooterCaption() { @@ -462,7 +465,7 @@ public class Grid<T> extends Composite implements /** * Sets text in the footer of the column. - * + * * @param caption * the text displayed in the footer of the column */ @@ -480,7 +483,7 @@ public class Grid<T> extends Composite implements /** * Is the column visible. By default all columns are visible. - * + * * @return <code>true</code> if the column is visible */ @Override @@ -490,7 +493,7 @@ public class Grid<T> extends Composite implements /** * Sets a column as visible in the grid. - * + * * @param visible * <code>true</code> if the column should be displayed in the * grid @@ -525,10 +528,10 @@ public class Grid<T> extends Composite implements * <p> * To support other types you will need to pass a custom renderer to the * column via the column constructor. - * + * * @param row * The row object that provides the cell content. - * + * * @return The cell content */ public abstract C getValue(T row); @@ -537,7 +540,7 @@ public class Grid<T> extends Composite implements * The renderer to render the cell width. By default renders the data as * a String or adds the widget into the cell if the column type is of * widget type. - * + * * @return The renderer to render the cell content with */ public Renderer<? super C> getRenderer() { @@ -546,7 +549,7 @@ public class Grid<T> extends Composite implements /** * Finds the index of this column instance - * + * */ private int findIndexOfColumn() { return grid.findVisibleColumnIndex((GridColumn<?, T>) this); @@ -555,7 +558,7 @@ public class Grid<T> extends Composite implements /** * Sets the pixel width of the column. Use a negative value for the grid * to autosize column based on content and available space - * + * * @param pixels * the width in pixels or negative for auto sizing */ @@ -572,7 +575,7 @@ public class Grid<T> extends Composite implements /** * Returns the pixel width of the column - * + * * @return pixel width of the column */ public int getWidth() { @@ -605,7 +608,7 @@ public class Grid<T> extends Composite implements /** * Constructs an updater for updating a header / footer - * + * * @param rows * The row container * @param inverted @@ -618,17 +621,17 @@ public class Grid<T> extends Composite implements /** * Gets the header/footer caption value - * + * * @param column * The column to get the value for. - * + * * @return The value that should be rendered for the column caption */ public abstract String getColumnValue(GridColumn<?, T> column); /** * Gets the group caption value - * + * * @param group * The group for with the caption value should be returned * @return The value that should be rendered for the column caption @@ -637,34 +640,34 @@ public class Grid<T> extends Composite implements /** * Is the row visible in the header/footer - * + * * @param row * the row to check - * + * * @return <code>true</code> if the row should be visible */ public abstract boolean isRowVisible(ColumnGroupRow<T> row); /** * Should the first row be visible - * + * * @return <code>true</code> if the first row should be visible */ public abstract boolean firstRowIsVisible(); /** * The renderer that renders the cell - * + * * @param column * The column for which the cell should be rendered - * + * * @return renderer used for rendering */ public abstract Renderer<String> getRenderer(GridColumn<?, T> column); /** * The renderer that renders the cell for column groups - * + * * @param group * The group that should be rendered * @return renderer used for rendering @@ -784,12 +787,14 @@ public class Grid<T> extends Composite implements public void setStylePrimaryName(String style) { super.setStylePrimaryName(style); escalator.setStylePrimaryName(style); + rowHasDataStyleName = getStylePrimaryName() + "-row-has-data"; + rowSelectedStyleName = getStylePrimaryName() + "-row-selected"; } /** * Creates the header updater that updates the escalator header rows from * the column and column group rows. - * + * * @return the updater that updates the data in the escalator. */ private EscalatorUpdater createHeaderUpdater() { @@ -865,26 +870,63 @@ public class Grid<T> extends Composite implements @Override public void update(Row row, Iterable<FlyweightCell> cellsToUpdate) { int rowIndex = row.getRow(); + Element rowElement = row.getElement(); T rowData = dataSource.getRow(rowIndex); - if (rowData == null) { - return; + + boolean hasData = rowData != null; + + // Assign stylename for rows with data + boolean usedToHaveData = rowElement + .hasClassName(rowHasDataStyleName); + + if (usedToHaveData != hasData) { + setStyleName(rowElement, rowHasDataStyleName, hasData); + } + + // Assign stylename for selected rows + if (hasData) { + setStyleName(rowElement, rowSelectedStyleName, + isSelected(rowData)); + } else if (usedToHaveData) { + setStyleName(rowElement, rowSelectedStyleName, false); } for (FlyweightCell cell : cellsToUpdate) { GridColumn<?, T> column = getColumnFromVisibleIndex(cell .getColumn()); + assert column != null : "Column was not found from cell (" + cell.getColumn() + "," + cell.getRow() + ")"; - Object value = column.getValue(rowData); - Renderer renderer = findRenderer(cell); - renderer.render(cell, value); - } - final String selectedClassName = getStylePrimaryName() - + "-row-selected"; + Renderer renderer = column.getRenderer(); - setStyleName(row.getElement(), selectedClassName, - isSelected(rowData)); + // Hide cell content if needed + if (renderer instanceof ComplexRenderer) { + ComplexRenderer clxRenderer = (ComplexRenderer) renderer; + if (hasData) { + if (!usedToHaveData) { + // Prepare cell for rendering + clxRenderer.setContentVisible(cell, true); + } + + Object value = column.getValue(rowData); + clxRenderer.render(cell, value); + + } else if (usedToHaveData) { + // Prepare cell for no data + clxRenderer.setContentVisible(cell, false); + } + + } else if (hasData) { + // Simple renderers just render + Object value = column.getValue(rowData); + renderer.render(cell, value); + + } else { + // Clear cell if there is no data + cell.getElement().removeAllChildren(); + } + } } @Override @@ -922,7 +964,7 @@ public class Grid<T> extends Composite implements /** * Creates the footer updater that updates the escalator footer rows from * the column and column group rows. - * + * * @return the updater that updates the data in the escalator. */ private EscalatorUpdater createFooterUpdater() { @@ -962,7 +1004,7 @@ public class Grid<T> extends Composite implements /** * Refreshes header or footer rows on demand - * + * * @param rows * The row container * @param firstRowIsVisible @@ -1014,7 +1056,7 @@ public class Grid<T> extends Composite implements /** * Adds a column as the last column in the grid. - * + * * @param column * the column to add */ @@ -1024,7 +1066,7 @@ public class Grid<T> extends Composite implements /** * Inserts a column into a specific position in the grid. - * + * * @param index * the index where the column should be inserted into * @param column @@ -1128,7 +1170,7 @@ public class Grid<T> extends Composite implements /** * Removes a column from the grid. - * + * * @param column * the column to remove */ @@ -1163,7 +1205,7 @@ public class Grid<T> extends Composite implements /** * Returns the amount of columns in the grid. - * + * * @return The number of columns in the grid */ public int getColumnCount() { @@ -1172,7 +1214,7 @@ public class Grid<T> extends Composite implements /** * Returns a list of columns in the grid. - * + * * @return A unmodifiable list of the columns in the grid */ public List<GridColumn<?, T>> getColumns() { @@ -1182,7 +1224,7 @@ public class Grid<T> extends Composite implements /** * Returns a column by its index in the grid. - * + * * @param index * the index of the column * @return The column in the given index @@ -1199,30 +1241,30 @@ public class Grid<T> extends Composite implements /** * Set the column headers visible. - * + * * <p> * A column header is a single cell header on top of each column reserved * for a specific header for that column. The column header can be set by * {@link GridColumn#setHeaderCaption(String)} and column headers cannot be * merged with other column headers. * </p> - * + * * <p> * All column headers occupy the first header row of the grid. If you do not * wish to show the column headers in the grid you should hide the row by * setting visibility of the header row to <code>false</code>. * </p> - * + * * <p> * If you want to merge the column headers into groups you can use * {@link ColumnGroupRow}s to group columns together and give them a common * header. See {@link #addColumnGroupRow()} for details. * </p> - * + * * <p> * The header row is by default visible. * </p> - * + * * @param visible * <code>true</code> if header rows should be visible */ @@ -1236,7 +1278,7 @@ public class Grid<T> extends Composite implements /** * Are the column headers visible - * + * * @return <code>true</code> if they are visible */ public boolean isColumnHeadersVisible() { @@ -1245,30 +1287,30 @@ public class Grid<T> extends Composite implements /** * Set the column footers visible. - * + * * <p> * A column footer is a single cell footer below of each column reserved for * a specific footer for that column. The column footer can be set by * {@link GridColumn#setFooterCaption(String)} and column footers cannot be * merged with other column footers. * </p> - * + * * <p> * All column footers occupy the first footer row of the grid. If you do not * wish to show the column footers in the grid you should hide the row by * setting visibility of the footer row to <code>false</code>. * </p> - * + * * <p> * If you want to merge the column footers into groups you can use * {@link ColumnGroupRow}s to group columns together and give them a common * footer. See {@link #addColumnGroupRow()} for details. * </p> - * + * * <p> * The footer row is by default hidden. * </p> - * + * * @param visible * <code>true</code> if the footer row should be visible */ @@ -1282,9 +1324,9 @@ public class Grid<T> extends Composite implements /** * Are the column footers visible - * + * * @return <code>true</code> if they are visible - * + * */ public boolean isColumnFootersVisible() { return columnFootersVisible; @@ -1292,15 +1334,15 @@ public class Grid<T> extends Composite implements /** * Adds a new column group row to the grid. - * + * * <p> * Column group rows are rendered in the header and footer of the grid. * Column group rows are made up of column groups which groups together * columns for adding a common auxiliary header or footer for the columns. * </p> - * + * * Example usage: - * + * * <pre> * // Add a new column group row to the grid * ColumnGroupRow row = grid.addColumnGroupRow(); @@ -1314,7 +1356,7 @@ public class Grid<T> extends Composite implements * // Set a common footer for "Column1" and "Column2" * column12.setFooter("Column 1&2"); * </pre> - * + * * @return a column group row instance you can use to add column groups */ public ColumnGroupRow<T> addColumnGroupRow() { @@ -1327,10 +1369,10 @@ public class Grid<T> extends Composite implements /** * Adds a new column group row to the grid at a specific index. - * + * * @see #addColumnGroupRow() {@link Grid#addColumnGroupRow()} for example * usage - * + * * @param rowIndex * the index where the column group row should be added * @return a column group row instance you can use to add column groups @@ -1345,7 +1387,7 @@ public class Grid<T> extends Composite implements /** * Removes a column group row - * + * * @param row * The row to remove */ @@ -1357,9 +1399,9 @@ public class Grid<T> extends Composite implements /** * Get the column group rows - * + * * @return a unmodifiable list of column group rows - * + * */ public List<ColumnGroupRow<T>> getColumnGroupRows() { return Collections.unmodifiableList(new ArrayList<ColumnGroupRow<T>>( @@ -1368,7 +1410,7 @@ public class Grid<T> extends Composite implements /** * Returns the column group for a row and column - * + * * @param row * The row of the column * @param column @@ -1392,7 +1434,7 @@ public class Grid<T> extends Composite implements * <p> * <em>Note:</em> This method will change the widget's size in the browser * only if {@link #getHeightMode()} returns {@link HeightMode#CSS}. - * + * * @see #setHeightMode(HeightMode) */ @Override @@ -1407,7 +1449,7 @@ public class Grid<T> extends Composite implements /** * Sets the data source used by this grid. - * + * * @param dataSource * the data source to use, not null * @throws IllegalArgumentException @@ -1460,7 +1502,7 @@ public class Grid<T> extends Composite implements * <p> * All columns up to and including the given column will be frozen in place * when the grid is scrolled sideways. - * + * * @param lastFrozenColumn * the rightmost column to freeze, or <code>null</code> to not * have any columns frozen @@ -1493,7 +1535,7 @@ public class Grid<T> extends Composite implements * <em>Note:</em> Most usually, this method returns the very value set with * {@link #setLastFrozenColumn(GridColumn)}. This value, however, can be * reset to <code>null</code> if the column is removed from this grid. - * + * * @return the rightmost frozen column in the grid, or <code>null</code> if * no columns are frozen. */ @@ -1513,7 +1555,7 @@ public class Grid<T> extends Composite implements /** * Scrolls to a certain row, using {@link ScrollDestination#ANY}. - * + * * @param rowIndex * zero-based index of the row to scroll to. * @throws IllegalArgumentException @@ -1527,7 +1569,7 @@ public class Grid<T> extends Composite implements /** * Scrolls to a certain row, using user-specified scroll destination. - * + * * @param rowIndex * zero-based index of the row to scroll to. * @param destination @@ -1546,7 +1588,7 @@ public class Grid<T> extends Composite implements /** * Scrolls to a certain row using only user-specified parameters. - * + * * @param rowIndex * zero-based index of the row to scroll to. * @param destination @@ -1603,7 +1645,7 @@ public class Grid<T> extends Composite implements * <p> * If Grid is currently not in {@link HeightMode#ROW}, the given value is * remembered, and applied once the mode is applied. - * + * * @param rows * The height in terms of number of rows displayed in Grid's * body. If Grid doesn't contain enough rows, white space is @@ -1615,7 +1657,7 @@ public class Grid<T> extends Composite implements * infinite} * @throws IllegalArgumentException * if {@code rows} is {@link Double#isNaN(double) NaN} - * + * * @see #setHeightMode(HeightMode) */ public void setHeightByRows(double rows) throws IllegalArgumentException { @@ -1627,7 +1669,7 @@ public class Grid<T> extends Composite implements * {@link #getHeightMode()} is {@link HeightMode#ROW}. * <p> * By default, it is {@value Escalator#DEFAULT_HEIGHT_BY_ROWS}. - * + * * @return the amount of rows that should be shown in Grid's body, while in * {@link HeightMode#ROW}. * @see #setHeightByRows(double) @@ -1647,7 +1689,7 @@ public class Grid<T> extends Composite implements * <em>Note:</em> If headers/footers are inserted or removed, the widget * will resize itself to still display the required amount of rows in its * body. It also takes the horizontal scrollbar into account. - * + * * @param heightMode * the mode in to which Grid should be set */ @@ -1669,7 +1711,7 @@ public class Grid<T> extends Composite implements * Returns the current {@link HeightMode} the Grid is in. * <p> * Defaults to {@link HeightMode#CSS}. - * + * * @return the current HeightMode */ public HeightMode getHeightMode() { @@ -1832,7 +1874,7 @@ public class Grid<T> extends Composite implements /** * Accesses the package private method Widget#setParent() - * + * * @param widget * The widget to access * @param parent @@ -1845,7 +1887,7 @@ public class Grid<T> extends Composite implements /** * Sets the current selection model. - * + * * @param selectionModel * a selection model implementation. * @throws IllegalArgumentException @@ -1863,7 +1905,7 @@ public class Grid<T> extends Composite implements /** * Gets a reference to the current selection model. - * + * * @return the currently used SelectionModel instance. */ public SelectionModel<T> getSelectionModel() { @@ -1874,7 +1916,7 @@ public class Grid<T> extends Composite implements * Sets current selection mode. * <p> * This is a shorthand method for {@link Grid#setSelectionModel}. - * + * * @param mode * a selection mode value * @see {@link SelectionMode}. @@ -1886,7 +1928,7 @@ public class Grid<T> extends Composite implements /** * Test if a row is selected. - * + * * @param row * a row object * @return true, if the current selection model considers the provided row @@ -1902,7 +1944,7 @@ public class Grid<T> extends Composite implements * Only selection models implementing {@link SelectionModel.Single} and * {@link SelectionModel.Multi} are supported; for anything else, an * exception will be thrown. - * + * * @param row * a row object * @return <code>true</code> iff the current selection changed @@ -1927,7 +1969,7 @@ public class Grid<T> extends Composite implements * Only selection models implementing {@link SelectionModel.Single} and * {@link SelectionModel.Multi} are supported; for anything else, an * exception will be thrown. - * + * * @param row * a row object * @return <code>true</code> iff the current selection changed @@ -1952,7 +1994,7 @@ public class Grid<T> extends Composite implements * Only selection models implementing {@link SelectionModel.Single} are * valid for this method; for anything else, use the * {@link Grid#getSelectedRows()} method. - * + * * @return a selected row reference, or null, if no row is selected * @throws IllegalStateException * if the current selection model is not an instance of @@ -1969,7 +2011,7 @@ public class Grid<T> extends Composite implements /** * Gets currently selected rows from the current selection model. - * + * * @return a non-null collection containing all currently selected rows. */ public Collection<T> getSelectedRows() { diff --git a/client/src/com/vaadin/client/ui/grid/renderers/ComplexRenderer.java b/client/src/com/vaadin/client/ui/grid/renderers/ComplexRenderer.java index cf3e43c88a..289f3809be 100644 --- a/client/src/com/vaadin/client/ui/grid/renderers/ComplexRenderer.java +++ b/client/src/com/vaadin/client/ui/grid/renderers/ComplexRenderer.java @@ -17,7 +17,10 @@ package com.vaadin.client.ui.grid.renderers; import java.util.Collection; +import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.Node; +import com.google.gwt.dom.client.Style.Visibility; import com.vaadin.client.ui.grid.Cell; import com.vaadin.client.ui.grid.FlyweightCell; import com.vaadin.client.ui.grid.Renderer; @@ -96,18 +99,33 @@ public abstract class ComplexRenderer<T> implements Renderer<T> { } /** - * Hides content by setting visibility: hidden to all elements inside the - * cell. Text nodes are left as is for now - renderers that add such to the - * root element need to implement explicit support hiding them + * Used by Grid to toggle whether to show actual data or just an empty + * placeholder while data is loading. This method is invoked whenever a cell + * changes between data being available and data missing. + * <p> + * Default implementation hides content by setting visibility: hidden to all + * elements inside the cell. Text nodes are left as is - renderers that add + * such to the root element need to implement explicit support hiding them. * * @param cell * The cell - * @param visible - * Is the cell content be visible - * @return <code>true</code> if the content should be set visible + * @param hasData + * Has the cell content been loaded from the data source + * */ - public boolean setContentVisible(FlyweightCell cell, boolean visible) { - return false; + public void setContentVisible(FlyweightCell cell, boolean hasData) { + Element cellElement = cell.getElement(); + for (int n = 0; n < cellElement.getChildCount(); n++) { + Node node = cellElement.getChild(n); + if (Element.is(node)) { + Element e = Element.as(node); + if (hasData) { + e.getStyle().clearVisibility(); + } else { + e.getStyle().setVisibility(Visibility.HIDDEN); + } + } + } } /** diff --git a/shared/src/com/vaadin/shared/ui/grid/GridConstants.java b/shared/src/com/vaadin/shared/ui/grid/GridConstants.java index d5fdd40120..8b264bf426 100644 --- a/shared/src/com/vaadin/shared/ui/grid/GridConstants.java +++ b/shared/src/com/vaadin/shared/ui/grid/GridConstants.java @@ -31,5 +31,4 @@ public final class GridConstants implements Serializable { * explicitly defined padding value. */ public static final int DEFAULT_PADDING = 0; - } diff --git a/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java b/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java index 2e1a9ab4a7..2f14ccf3f3 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java @@ -16,6 +16,7 @@ package com.vaadin.tests.components.grid; import static org.junit.Assert.assertEquals; +import junit.framework.Assert; import org.junit.Test; import org.openqa.selenium.Alert; @@ -38,15 +39,31 @@ import com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers; */ public class GridClientRenderers extends MultiBrowserTest { + private int latency = 0; + @Override protected Class<?> getUIClass() { return GridClientColumnRenderers.class; } + @Override + protected String getDeploymentPath() { + if (latency > 0) { + return super.getDeploymentPath() + "?latency=" + latency; + } + return super.getDeploymentPath(); + } + @ServerClass("com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers.GridController") public static class MyClientGridElement extends GridElement { } + @Override + public void setup() throws Exception { + latency = 0; // reset + super.setup(); + } + @Test public void addWidgetRenderer() throws Exception { openTestURL(); @@ -88,7 +105,60 @@ public class GridClientRenderers extends MultiBrowserTest { assertEquals(alert.getText(), "Click"); } + @Test + public void rowsWithDataHasStyleName() throws Exception { + + // Simulate network latency with 1000ms + latency = 1000; + + openTestURL(); + + TestBenchElement row = getGrid().getRow(1); + String className = row.getAttribute("class"); + Assert.assertFalse(className.contains("v-grid-row-has-data")); + + // Wait for data to arrive + sleep(3000); + + row = getGrid().getRow(1); + className = row.getAttribute("class"); + Assert.assertTrue(className.contains("v-grid-row-has-data")); + } + + @Test + public void complexRendererSetVisibleContent() throws Exception { + + // Simulate network latency with 1000ms + latency = 1000; + + openTestURL(); + + addColumn(Renderers.CPLX_RENDERER); + + // Fetch data + getGrid().scrollToRow(50); + + // Cell should be red (setContentVisible set cell red) + String backgroundColor = getGrid().getCell(1, 1).getCssValue( + "backgroundColor"); + assertEquals("rgba(255, 0, 0, 1)", backgroundColor); + + // Wait for data to arrive + sleep(3000); + + // Cell should no longer be red + backgroundColor = getGrid().getCell(1, 1) + .getCssValue("backgroundColor"); + assertEquals("rgba(255, 255, 255, 1)", backgroundColor); + } + private GridElement getGrid() { return $(MyClientGridElement.class).first(); } + + private void addColumn(Renderers renderer) { + // Add widget renderer column + $(NativeSelectElement.class).first().selectByText(renderer.toString()); + $(NativeButtonElement.class).caption("Add").first().click(); + } } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java index a4403f54fc..e4d8042605 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java @@ -21,15 +21,20 @@ import java.util.List; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.Window.Location; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.HasWidgets; +import com.vaadin.client.data.DataChangeHandler; +import com.vaadin.client.data.DataSource; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.grid.FlyweightCell; import com.vaadin.client.ui.grid.Grid; import com.vaadin.client.ui.grid.GridColumn; import com.vaadin.client.ui.grid.Renderer; import com.vaadin.client.ui.grid.datasources.ListDataSource; +import com.vaadin.client.ui.grid.renderers.ComplexRenderer; import com.vaadin.client.ui.grid.renderers.DateRenderer; import com.vaadin.client.ui.grid.renderers.HtmlRenderer; import com.vaadin.client.ui.grid.renderers.NumberRenderer; @@ -43,7 +48,57 @@ public class GridClientColumnRendererConnector extends AbstractComponentConnector { public static enum Renderers { - TEXT_RENDERER, WIDGET_RENDERER, HTML_RENDERER, NUMBER_RENDERER, DATE_RENDERER; + TEXT_RENDERER, WIDGET_RENDERER, HTML_RENDERER, NUMBER_RENDERER, DATE_RENDERER, CPLX_RENDERER; + } + + /** + * Datasource for simulating network latency + */ + private class DelayedDataSource implements DataSource<String> { + + private DataSource<String> ds; + private int firstRowIndex; + private int numberOfRows; + private DataChangeHandler dataChangeHandler; + private int latency; + + public DelayedDataSource(DataSource<String> ds, int latency) { + this.ds = ds; + this.latency = latency; + } + + @Override + public void ensureAvailability(final int firstRowIndex, + final int numberOfRows) { + new Timer() { + + @Override + public void run() { + DelayedDataSource.this.firstRowIndex = firstRowIndex; + DelayedDataSource.this.numberOfRows = numberOfRows; + dataChangeHandler.dataUpdated(firstRowIndex, numberOfRows); + } + }.schedule(latency); + } + + @Override + public String getRow(int rowIndex) { + if (rowIndex >= firstRowIndex + && rowIndex <= firstRowIndex + numberOfRows) { + return ds.getRow(rowIndex); + } + return null; + } + + @Override + public int getEstimatedSize() { + return ds.getEstimatedSize(); + } + + @Override + public void setDataChangeHandler(DataChangeHandler dataChangeHandler) { + this.dataChangeHandler = dataChangeHandler; + } } @Override @@ -58,7 +113,13 @@ public class GridClientColumnRendererConnector extends } // Provide data as data source - grid.setDataSource(new ListDataSource<String>(columnData)); + if (Location.getParameter("latency") != null) { + grid.setDataSource(new DelayedDataSource( + new ListDataSource<String>(columnData), Integer + .parseInt(Location.getParameter("latency")))); + } else { + grid.setDataSource(new ListDataSource<String>(columnData)); + } // Add a column to display the data in grid.addColumn(createColumnWithRenderer(Renderers.TEXT_RENDERER)); @@ -141,6 +202,27 @@ public class GridClientColumnRendererConnector extends case DATE_RENDERER: return new DateRenderer(); + case CPLX_RENDERER: + return new ComplexRenderer<String>() { + + @Override + public void render(FlyweightCell cell, String data) { + cell.getElement().setInnerHTML("<span>" + data + "</span>"); + cell.getElement().getStyle().clearBackgroundColor(); + } + + @Override + public void setContentVisible(FlyweightCell cell, + boolean hasData) { + + // Visualize content visible property + cell.getElement().getStyle() + .setBackgroundColor(hasData ? "green" : "red"); + + super.setContentVisible(cell, hasData); + } + }; + default: return new TextRenderer(); } |