summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java238
-rw-r--r--client/src/com/vaadin/client/ui/grid/renderers/ComplexRenderer.java34
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/GridConstants.java1
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java70
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java86
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 &quot;Column1&quot; and &quot;Column2&quot;
* column12.setFooter(&quot;Column 1&amp;2&quot;);
* </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();
}