Browse Source

Redesign user-defined column identifiers for Grid (#7983)

Closes vaadin/framework8-issues#494
tags/8.0.0.alpha10
Teemu Suo-Anttila 7 years ago
parent
commit
9d35813566
22 changed files with 416 additions and 303 deletions
  1. 1
    1
      client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java
  2. 138
    107
      server/src/main/java/com/vaadin/ui/Grid.java
  3. 3
    2
      server/src/main/java/com/vaadin/ui/components/grid/EditorImpl.java
  4. 3
    3
      server/src/main/java/com/vaadin/ui/components/grid/Header.java
  5. 79
    13
      server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java
  6. 7
    1
      server/src/main/java/com/vaadin/ui/renderers/AbstractRenderer.java
  7. 5
    5
      server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java
  8. 91
    83
      server/src/test/java/com/vaadin/tests/server/component/grid/GridDeclarativeTest.java
  9. 7
    5
      server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java
  10. 6
    4
      server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java
  11. 4
    17
      server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
  12. 1
    1
      shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java
  13. 16
    15
      shared/src/main/java/com/vaadin/shared/ui/grid/GridServerRpc.java
  14. 2
    1
      uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java
  15. 7
    5
      uitest/src/main/java/com/vaadin/tests/components/grid/GridClickableRenderers.java
  16. 7
    6
      uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java
  17. 5
    4
      uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnResizing.java
  18. 2
    2
      uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java
  19. 5
    4
      uitest/src/main/java/com/vaadin/tests/components/grid/JavaScriptRenderers.java
  20. 2
    1
      uitest/src/main/java/com/vaadin/tests/components/grid/basics/RefreshDataProvider.java
  21. 15
    13
      uitest/src/main/java/com/vaadin/tests/contextclick/GridContextClick.java
  22. 10
    10
      uitest/src/main/java/com/vaadin/tests/performance/GridMemory.java

+ 1
- 1
client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java View File

@@ -74,7 +74,7 @@ public class ColumnConnector extends AbstractExtensionConnector {
}
};
column.setRenderer(getRendererConnector().getRenderer());
getParent().addColumn(column, getState().id);
getParent().addColumn(column, getState().internalId);
}

@SuppressWarnings("unchecked")

+ 138
- 107
server/src/main/java/com/vaadin/ui/Grid.java View File

@@ -78,7 +78,6 @@ import com.vaadin.shared.ui.grid.GridState;
import com.vaadin.shared.ui.grid.GridStaticCellType;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.shared.ui.grid.SectionState;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.Grid.FooterRow;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.components.grid.AbstractSelectionModel;
@@ -338,7 +337,7 @@ public class Grid<T> extends AbstractListing<T>

/**
* Generates the sort orders when rows are sorted by a column.
*
*
* @see Column#setSortOrderProvider
*
* @since 8.0
@@ -758,41 +757,46 @@ public class Grid<T> extends AbstractListing<T>
protected AbstractGridExtensionState getState(boolean markAsDirty) {
return (AbstractGridExtensionState) super.getState(markAsDirty);
}

protected String getInternalIdForColumn(Column<T, ?> column) {
return getParent().getInternalIdForColumn(column);
}
}

private final class GridServerRpcImpl implements GridServerRpc {
@Override
public void sort(String[] columnIds, SortDirection[] directions,
public void sort(String[] columnInternalIds, SortDirection[] directions,
boolean isUserOriginated) {
assert columnIds.length == directions.length : "Column and sort direction counts don't match.";

assert columnInternalIds.length == directions.length : "Column and sort direction counts don't match.";

List<SortOrder<Column<T, ?>>> list = new ArrayList<>(
directions.length);
for (int i = 0; i < columnIds.length; ++i) {
Column<T, ?> column = columnKeys.get(columnIds[i]);
for (int i = 0; i < columnInternalIds.length; ++i) {
Column<T, ?> column = columnKeys.get(columnInternalIds[i]);
list.add(new SortOrder<>(column, directions[i]));
}
setSortOrder(list, isUserOriginated);
}

@Override
public void itemClick(String rowKey, String columnId,
public void itemClick(String rowKey, String columnInternalId,
MouseEventDetails details) {
Column<T, ?> column = columnKeys.containsKey(columnId)
? columnKeys.get(columnId) : null;
Column<T, ?> column = getColumnByInternalId(columnInternalId);
T item = getDataCommunicator().getKeyMapper().get(rowKey);
fireEvent(new ItemClick<>(Grid.this, column, item, details));
}

@Override
public void contextClick(int rowIndex, String rowKey, String columnId,
Section section, MouseEventDetails details) {
public void contextClick(int rowIndex, String rowKey,
String columnInternalId, Section section,
MouseEventDetails details) {
T item = null;
if (rowKey != null) {
item = getDataCommunicator().getKeyMapper().get(rowKey);
}
fireEvent(new GridContextClickEvent<>(Grid.this, details, section,
rowIndex, item, getColumn(columnId)));
rowIndex, item, getColumnByInternalId(columnInternalId)));
}

@Override
@@ -832,8 +836,8 @@ public class Grid<T> extends AbstractListing<T>
}

@Override
public void columnVisibilityChanged(String id, boolean hidden) {
Column<T, ?> column = getColumn(id);
public void columnVisibilityChanged(String internalId, boolean hidden) {
Column<T, ?> column = getColumnByInternalId(internalId);
ColumnState columnState = column.getState(false);
if (columnState.hidden != hidden) {
columnState.hidden = hidden;
@@ -842,8 +846,8 @@ public class Grid<T> extends AbstractListing<T>
}

@Override
public void columnResized(String id, double pixels) {
final Column<T, ?> column = getColumn(id);
public void columnResized(String internalId, double pixels) {
final Column<T, ?> column = getColumnByInternalId(internalId);
if (column != null && column.isResizable()) {
column.getState().width = pixels;
fireColumnResizeEvent(column, true);
@@ -992,12 +996,12 @@ public class Grid<T> extends AbstractListing<T>

private EditorComponentGenerator<T> componentGenerator;

private String userId;

/**
* Constructs a new Column configuration with given header caption,
* renderer and value provider.
*
* @param caption
* the header caption
* @param valueProvider
* the function to get values from items
* @param renderer
@@ -1006,7 +1010,6 @@ public class Grid<T> extends AbstractListing<T>
protected Column(String caption,
ValueProvider<T, ? extends V> valueProvider,
Renderer<V> renderer) {
Objects.requireNonNull(caption, "Header caption can't be null");
Objects.requireNonNull(valueProvider,
"Value provider can't be null");
Objects.requireNonNull(renderer, "Renderer can't be null");
@@ -1016,7 +1019,7 @@ public class Grid<T> extends AbstractListing<T>
this.valueProvider = valueProvider;
state.renderer = renderer;

state.caption = caption;
state.caption = "";
sortOrderProvider = d -> Stream.of();

// Add the renderer as a child extension of this extension, thus
@@ -1150,8 +1153,8 @@ public class Grid<T> extends AbstractListing<T>
*
* @return the identifier string
*/
public String getId() {
return getState(false).id;
private String getInternalId() {
return getState(false).internalId;
}

/**
@@ -1160,9 +1163,36 @@ public class Grid<T> extends AbstractListing<T>
* @param id
* the identifier string
*/
private void setId(String id) {
private void setInternalId(String id) {
Objects.requireNonNull(id, "Communication ID can't be null");
getState().id = id;
getState().internalId = id;
}

/**
* Returns the user-defined identifier for this column.
*
* @return the identifier string
*/
public String getId() {
return userId;
}

/**
* Sets the user-defined identifier to map this column. The identifier
* can be used for example in {@link Grid#getColumn(String)}.
*
* @param id
* the identifier string
*/
public Column<T, V> setId(String id) {
Objects.requireNonNull(id, "Column identifier cannot be null");
if (this.userId != null) {
throw new IllegalStateException(
"Column identifier cannot be changed");
}
this.userId = id;
getParent().setColumnId(id, this);
return this;
}

/**
@@ -1202,7 +1232,7 @@ public class Grid<T> extends AbstractListing<T>

HeaderRow row = getParent().getDefaultHeaderRow();
if (row != null) {
row.getCell(getId()).setText(caption);
row.getCell(this).setText(caption);
}

return this;
@@ -1804,6 +1834,10 @@ public class Grid<T> extends AbstractListing<T>

ColumnState defaultState = new ColumnState();

if (getId() == null) {
setId("column" + getParent().getColumns().indexOf(this));
}

DesignAttributeHandler.writeAttribute("column-id", attributes,
getId(), null, String.class, designContext);

@@ -1943,9 +1977,7 @@ public class Grid<T> extends AbstractListing<T>
* @throws IllegalArgumentException
* if there is no such column in the grid
*/
public default HeaderCell getCell(Column<?, ?> column) {
return getCell(column.getId());
}
public HeaderCell getCell(Column<?, ?> column);

/**
* Merges column cells in the row. Original cells are hidden, and new
@@ -2072,9 +2104,7 @@ public class Grid<T> extends AbstractListing<T>
* @throws IllegalArgumentException
* if there is no such column in the grid
*/
public default FooterCell getCell(Column<?, ?> column) {
return getCell(column.getId());
}
public FooterCell getCell(Column<?, ?> column);

/**
* Merges column cells in the row. Original cells are hidden, and new
@@ -2350,8 +2380,14 @@ public class Grid<T> extends AbstractListing<T>
}

@Override
protected Collection<Column<T, ?>> getColumns() {
return Grid.this.getColumns();
protected Column<?, ?> getColumnByInternalId(String internalId) {
return getGrid().getColumnByInternalId(internalId);
}

@Override
@SuppressWarnings("unchecked")
protected String getInternalIdForColumn(Column<?, ?> column) {
return getGrid().getInternalIdForColumn((Column<T, ?>) column);
}
};

@@ -2368,13 +2404,20 @@ public class Grid<T> extends AbstractListing<T>
}

@Override
protected Collection<Column<T, ?>> getColumns() {
return Grid.this.getColumns();
protected Column<?, ?> getColumnByInternalId(String internalId) {
return getGrid().getColumnByInternalId(internalId);
}

@Override
@SuppressWarnings("unchecked")
protected String getInternalIdForColumn(Column<?, ?> column) {
return getGrid().getInternalIdForColumn((Column<T, ?>) column);
}
};

private final Set<Column<T, ?>> columnSet = new LinkedHashSet<>();
private final Map<String, Column<T, ?>> columnKeys = new HashMap<>();
private final Map<String, Column<T, ?>> columnIds = new HashMap<>();

private final List<SortOrder<Column<T, ?>>> sortOrder = new ArrayList<>();
private final DetailsManager<T> detailsManager;
@@ -2430,65 +2473,11 @@ public class Grid<T> extends AbstractListing<T>
userOriginated));
}

/**
* Adds a new column to this {@link Grid} with given identifier, typed
* renderer and value provider.
*
* @param identifier
* the identifier in camel case for the new column
* @param valueProvider
* the value provider
* @param renderer
* the column value class
* @param <V>
* the column value type
*
* @return the new column
* @throws IllegalArgumentException
* if the same identifier is used for multiple columns
*
* @see AbstractRenderer
*/
public <V> Column<T, V> addColumn(String identifier,
ValueProvider<T, ? extends V> valueProvider,
AbstractRenderer<? super T, V> renderer)
throws IllegalArgumentException {
if (columnKeys.containsKey(identifier)) {
throw new IllegalArgumentException(
"Multiple columns with the same identifier: " + identifier);
}

final Column<T, V> column = new Column<>(
SharedUtil.camelCaseToHumanFriendly(identifier), valueProvider,
renderer);
addColumn(identifier, column);
return column;
}

/**
* Adds a new text column to this {@link Grid} with given identifier and
* string value provider. The column will use a {@link TextRenderer}.
*
* @param identifier
* the header caption
* @param valueProvider
* the value provider
*
* @return the new column
* @throws IllegalArgumentException
* if the same identifier is used for multiple columns
*/
public Column<T, String> addColumn(String identifier,
ValueProvider<T, String> valueProvider) {
return addColumn(identifier, valueProvider, new TextRenderer());
}

/**
* Adds a new text column to this {@link Grid} with a value provider. The
* column will use a {@link TextRenderer}. The value is converted to a
* String using {@link Object#toString()}. Sorting in memory is executed by
* comparing the String values. Identifier for the column is generated
* automatically.
* comparing the String values.
*
* @param valueProvider
* the value provider
@@ -2496,14 +2485,13 @@ public class Grid<T> extends AbstractListing<T>
* @return the new column
*/
public Column<T, String> addColumn(ValueProvider<T, String> valueProvider) {
return addColumn(getGeneratedIdentifier(),
t -> String.valueOf(valueProvider.apply(t)),
return addColumn(t -> String.valueOf(valueProvider.apply(t)),
new TextRenderer());
}

/**
* Adds a new column to this {@link Grid} with typed renderer and value
* provider. Identifier for the column is generated automatically.
* provider.
*
* @param valueProvider
* the value provider
@@ -2519,7 +2507,11 @@ public class Grid<T> extends AbstractListing<T>
public <V> Column<T, V> addColumn(
ValueProvider<T, ? extends V> valueProvider,
AbstractRenderer<? super T, V> renderer) {
return addColumn(getGeneratedIdentifier(), valueProvider, renderer);
String generatedIdentifier = getGeneratedIdentifier();
Column<T, V> column = new Column<>("Column " + generatedIdentifier,
valueProvider, renderer);
addColumn(generatedIdentifier, column);
return column;
}

private void addColumn(String identifier, Column<T, ?> column) {
@@ -2530,15 +2522,14 @@ public class Grid<T> extends AbstractListing<T>
column.extend(this);
columnSet.add(column);
columnKeys.put(identifier, column);
column.setId(identifier);
column.setInternalId(identifier);
addDataGenerator(column);

getState().columnOrder.add(identifier);
getHeader().addColumn(identifier);

if (getDefaultHeaderRow() != null) {
getDefaultHeaderRow().getCell(identifier)
.setText(column.getCaption());
getDefaultHeaderRow().getCell(column).setText(column.getCaption());
}
}

@@ -2550,8 +2541,9 @@ public class Grid<T> extends AbstractListing<T>
*/
public void removeColumn(Column<T, ?> column) {
if (columnSet.remove(column)) {
String columnId = column.getId();
String columnId = column.getInternalId();
columnKeys.remove(columnId);
columnIds.remove(column.getId());
column.remove();
getHeader().removeColumn(columnId);
getFooter().removeColumn(columnId);
@@ -2603,7 +2595,7 @@ public class Grid<T> extends AbstractListing<T>
*/
public List<Column<T, ?>> getColumns() {
return Collections.unmodifiableList(getState(false).columnOrder.stream()
.map(this::getColumn).collect(Collectors.toList()));
.map(columnKeys::get).collect(Collectors.toList()));
}

/**
@@ -2611,10 +2603,10 @@ public class Grid<T> extends AbstractListing<T>
*
* @param columnId
* the identifier of the column to get
* @return the column corresponding to the given column id
* @return the column corresponding to the given column identifier
*/
public Column<T, ?> getColumn(String columnId) {
return columnKeys.get(columnId);
return columnIds.get(columnId);
}

@Override
@@ -3218,7 +3210,7 @@ public class Grid<T> extends AbstractListing<T>
}

private String getGeneratedIdentifier() {
String columnId = "generatedColumn" + counter;
String columnId = "" + counter;
counter++;
return columnId;
}
@@ -3235,7 +3227,7 @@ public class Grid<T> extends AbstractListing<T>
List<String> columnOrder = new ArrayList<>();
for (Column<T, ?> column : columns) {
if (columnSet.contains(column)) {
columnOrder.add(column.getId());
columnOrder.add(column.getInternalId());
} else {
throw new IllegalArgumentException(
"setColumnOrder should not be called "
@@ -3644,12 +3636,12 @@ public class Grid<T> extends AbstractListing<T>
for (Element col : colgroups.get(0).getElementsByTag("col")) {
String id = DesignAttributeHandler.readAttribute("column-id",
col.attributes(), null, String.class);
Column<T, String> column;
DeclarativeValueProvider<T> provider = new DeclarativeValueProvider<>();
Column<T, String> column = new Column<>("", provider,
new HtmlRenderer());
addColumn(getGeneratedIdentifier(), column);
if (id != null) {
column = addColumn(id, provider, new HtmlRenderer());
} else {
column = addColumn(provider, new HtmlRenderer());
column.setId(id);
}
providers.add(provider);
column.readDesign(col, context);
@@ -3741,6 +3733,21 @@ public class Grid<T> extends AbstractListing<T>
return mode;
}

/**
* Sets a user-defined identifier for given column.
*
* @param column
* the column
* @param id
* the user-defined identifier
*/
protected void setColumnId(String id, Column<T, ?> column) {
if (columnIds.containsKey(id)) {
throw new IllegalArgumentException("Duplicate ID for columns");
}
columnIds.put(id, column);
}

@Override
protected Collection<String> getCustomAttributes() {
Collection<String> result = super.getCustomAttributes();
@@ -3756,6 +3763,30 @@ public class Grid<T> extends AbstractListing<T>
return result;
}

/**
* Returns a column identified by its internal id. This id should not be
* confused with the user-defined identifier.
*
* @param columnId
* the internal id of column
* @return column identified by internal id
*/
protected Column<T, ?> getColumnByInternalId(String columnId) {
return columnKeys.get(columnId);
}

/**
* Returns the internal id for given column. This id should not be confused
* with the user-defined identifier.
*
* @param column
* the column
* @return internal id of given column
*/
protected String getInternalIdForColumn(Column<T, ?> column) {
return column.getInternalId();
}

private void setSortOrder(List<SortOrder<Column<T, ?>>> order,
boolean userOriginated) {
Objects.requireNonNull(order, "Sort order list cannot be null");

+ 3
- 2
server/src/main/java/com/vaadin/ui/components/grid/EditorImpl.java View File

@@ -78,7 +78,8 @@ public class EditorImpl<T> extends AbstractGridExtension<T>
String message = errorGenerator.apply(fieldToColumn, status);

List<String> columnIds = fieldToColumn.values().stream()
.map(Column::getId).collect(Collectors.toList());
.map(column -> getInternalIdForColumn(column))
.collect(Collectors.toList());

rpc.setErrorMessage(message, columnIds);
}
@@ -221,7 +222,7 @@ public class EditorImpl<T> extends AbstractGridExtension<T>
.apply(edited);
addComponentToGrid(component);
columnFields.put(c, component);
getState().columnFields.put(c.getId(),
getState().columnFields.put(getInternalIdForColumn(c),
component.getConnectorId());
});
}

+ 3
- 3
server/src/main/java/com/vaadin/ui/components/grid/Header.java View File

@@ -1,12 +1,12 @@
/*
* 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

+ 79
- 13
server/src/main/java/com/vaadin/ui/components/grid/StaticSection.java View File

@@ -17,7 +17,6 @@ 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.HashSet;
import java.util.Iterator;
@@ -98,16 +97,45 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
protected abstract String getCellTagName();

/**
* Adds a cell to this section, corresponding to the given column id.
* Adds a cell to this section, corresponding to the given user-defined
* column id.
*
* @param columnId
* the id of the column for which to add a cell
*/
protected void addCell(String columnId) {
Column<?, ?> column = section.getGrid().getColumn(columnId);
Objects.requireNonNull(column,
"No column matching given identifier");
addCell(column);
}

/**
* Adds a cell to this section for given column.
*
* @param column
* the column for which to add a cell
*/
protected void addCell(Column<?, ?> column) {
if (!section.getGrid().getColumns().contains(column)) {
throw new IllegalArgumentException(
"Given column does not exist in this Grid");
}
internalAddCell(section.getInternalIdForColumn(column));
}

/**
* Adds a cell to this section, corresponding to the given internal
* column id.
*
* @param internalId
* the internal id of the column for which to add a cell
*/
protected void internalAddCell(String internalId) {
CELL cell = createCell();
cell.setColumnId(columnId);
cells.put(columnId, cell);
rowState.cells.put(columnId, cell.getCellState());
cell.setColumnId(internalId);
cells.put(internalId, cell);
rowState.cells.put(internalId, cell.getCellState());
}

/**
@@ -153,10 +181,43 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
* if no cell was found for the column id
*/
public CELL getCell(String columnId) {
CELL cell = cells.get(columnId);
Column<?, ?> column = section.getGrid().getColumn(columnId);
Objects.requireNonNull(column,
"No column matching given identifier");
return getCell(column);
}

/**
* Returns the cell in this section that corresponds to the given
* column.
*
* @param column
* the column
* @return the cell for the given column
*
* @throws IllegalArgumentException
* if no cell was found for the column
*/
public CELL getCell(Column<?, ?> column) {
return internalGetCell(section.getInternalIdForColumn(column));
}

/**
* Returns the cell in this section that corresponds to the given
* internal column id.
*
* @param internalId
* the internal id of the column
* @return the cell for the given column
*
* @throws IllegalArgumentException
* if no cell was found for the column id
*/
protected CELL internalGetCell(String internalId) {
CELL cell = cells.get(internalId);
if (cell == null) {
throw new IllegalArgumentException(
"No cell found for column id " + columnId);
"No cell found for column id " + internalId);
}
return cell;
}
@@ -245,6 +306,7 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
.getValue().contains(entry.getKey()))
.findFirst();
Stream<String> columnIds = Stream.of(entry.getKey());

if (groupCell.isPresent()) {
Set<String> orderedSet = new LinkedHashSet<>(
cells.keySet());
@@ -259,12 +321,14 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
entry.getValue().getCellState());
}
cellElement.attr("column-ids",
columnIds.collect(Collectors.joining(",")));
columnIds.map(section::getColumnByInternalId)
.map(Column::getId)
.collect(Collectors.joining(",")));
}
}

/**
*
*
* Writes declarative design for the cell using its {@code state} to the
* given table cell element.
* <p>
@@ -272,7 +336,7 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
* sometimes there is no a reference to the cell which should be written
* (merged cell) but only its state is available (the cell is virtual
* and is not stored).
*
*
* @param cellElement
* Element to write design to
* @param context
@@ -509,7 +573,9 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>

protected abstract Grid<?> getGrid();

protected abstract Collection<? extends Column<?, ?>> getColumns();
protected abstract Column<?, ?> getColumnByInternalId(String internalId);

protected abstract String getInternalIdForColumn(Column<?, ?> column);

/**
* Marks the state of this section as modified.
@@ -532,7 +598,7 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
rows.add(index, row);
getState(true).rows.add(index, row.getRowState());

getColumns().stream().forEach(column -> row.addCell(column.getId()));
getGrid().getColumns().stream().forEach(row::addCell);

return row;
}
@@ -599,7 +665,7 @@ public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
*/
public void addColumn(String columnId) {
for (ROW row : rows) {
row.addCell(columnId);
row.internalAddCell(columnId);
}
}


+ 7
- 1
server/src/main/java/com/vaadin/ui/renderers/AbstractRenderer.java View File

@@ -149,7 +149,8 @@ public abstract class AbstractRenderer<T, V> extends AbstractExtension
* indicating the source grid of possible events emitted by this renderer,
* such as {@link RendererClickEvent}s.
*
* @return the grid this renderer is attached to or null if unattached
* @return the grid this renderer is attached to or {@code null} if
* unattached
*/
@SuppressWarnings("unchecked")
protected Grid<T> getParentGrid() {
@@ -159,6 +160,11 @@ public abstract class AbstractRenderer<T, V> extends AbstractExtension
return (Grid<T>) super.getParent().getParent();
}

@Override
public Column<T, V> getParent() {
return (Column<T, V>) super.getParent();
}

@Override
protected AbstractRendererState getState() {
return (AbstractRendererState) super.getState();

+ 5
- 5
server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java View File

@@ -73,10 +73,10 @@ public abstract class ClickableRenderer<T, V> extends AbstractRenderer<T, V> {
public static class RendererClickEvent<T> extends ClickEvent {

private final T item;
private final Column column;
private final Column<T, ?> column;

protected RendererClickEvent(Grid<T> source, T item, Column column,
MouseEventDetails mouseEventDetails) {
protected RendererClickEvent(Grid<T> source, T item,
Column<T, ?> column, MouseEventDetails mouseEventDetails) {
super(source, mouseEventDetails);
this.item = item;
this.column = column;
@@ -96,7 +96,7 @@ public abstract class ClickableRenderer<T, V> extends AbstractRenderer<T, V> {
*
* @return the column of the click event
*/
public Column getColumn() {
public Column<T, ?> getColumn() {
return column;
}
}
@@ -132,7 +132,7 @@ public abstract class ClickableRenderer<T, V> extends AbstractRenderer<T, V> {
MouseEventDetails mouseDetails) -> {
Grid<T> grid = getParentGrid();
T item = grid.getDataCommunicator().getKeyMapper().get(rowKey);
Column column = grid.getColumn(columnId);
Column<T, V> column = getParent();

fireEvent(
new RendererClickEvent<>(grid, item, column, mouseDetails));

+ 91
- 83
server/src/test/java/com/vaadin/tests/server/component/grid/GridDeclarativeTest.java View File

@@ -56,8 +56,8 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
HeightMode heightMode = HeightMode.ROW;
double heightByRows = 13.7d;

grid.addColumn(Person::getFirstName);
grid.addColumn("id", Person::getLastName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setId("id").setCaption("Id");

grid.setFrozenColumnCount(frozenColumns);
grid.setSelectionMode(SelectionMode.MULTI);
@@ -66,9 +66,9 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {

String design = String.format(
"<%s height-mode='%s' frozen-columns='%d' rows='%s' selection-mode='%s'><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
+ "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable>" + "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead></table></%s>",
getComponentTag(),
@@ -85,11 +85,12 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
public void mergedHeaderCells() {
Grid<Person> grid = new Grid<>();

Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
Column<Person, String> column2 = grid.addColumn("id",
Person::getLastName);
Column<Person, String> column3 = grid.addColumn("mail",
Person::getEmail);
Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
.setCaption("First Name");
Column<Person, String> column2 = grid.addColumn(Person::getLastName)
.setId("id").setCaption("Id");
Column<Person, String> column3 = grid.addColumn(Person::getEmail)
.setId("mail").setCaption("Mail");

HeaderRow header = grid.addHeaderRowAt(1);
String headerRowText1 = "foo";
@@ -99,17 +100,19 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
String headerRowText3 = "foobar";
join.setText(headerRowText3);

String design = String.format("<%s><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
+ "<col column-id='id' sortable>"
+ "<col column-id='mail' sortable>" + "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<th plain-text column-ids='id'>Id</th>"
+ "<th plain-text column-ids='mail'>Mail</th></tr>"
+ "<tr><th plain-text column-ids='generatedColumn0'>%s</th>"
+ "<th colspan='2' plain-text column-ids='id,mail'>foobar</th></tr>"
+ "</thead></table></%s>", getComponentTag(), headerRowText1,
headerRowText3, getComponentTag());
String design = String.format(
"<%s><table><colgroup>" + "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable>"
+ "<col column-id='mail' sortable>"
+ "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th>"
+ "<th plain-text column-ids='mail'>Mail</th></tr>"
+ "<tr><th plain-text column-ids='column0'>%s</th>"
+ "<th colspan='2' plain-text column-ids='id,mail'>foobar</th></tr>"
+ "</thead></table></%s>",
getComponentTag(), headerRowText1, headerRowText3,
getComponentTag());

testRead(design, grid);
testWrite(design, grid);
@@ -119,11 +122,12 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
public void mergedFooterCells() {
Grid<Person> grid = new Grid<>();

Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
Column<Person, String> column2 = grid.addColumn("id",
Person::getLastName);
Column<Person, String> column3 = grid.addColumn("mail",
Person::getEmail);
Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
.setCaption("First Name");
Column<Person, String> column2 = grid.addColumn(Person::getLastName)
.setId("id").setCaption("Id");
Column<Person, String> column3 = grid.addColumn(Person::getEmail)
.setId("mail").setCaption("Mail");

FooterRow footer = grid.addFooterRowAt(0);

@@ -137,17 +141,19 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
String footerRowText2 = "foobar";
footer.join(cell2, cell3).setHtml(footerRowText2);

String design = String.format("<%s><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
+ "<col column-id='id' sortable>"
+ "<col column-id='mail' sortable>" + "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<th plain-text column-ids='id'>Id</th>"
+ "<th plain-text column-ids='mail'>Mail</th></tr></thead>"
+ "<tfoot><tr><td plain-text column-ids='generatedColumn0'>%s</td>"
+ "<td colspan='2' column-ids='id,mail'>%s</td></tr></tfoot>"
+ "</table></%s>", getComponentTag(), footerRowText1,
footerRowText2, getComponentTag());
String design = String.format(
"<%s><table><colgroup>" + "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable>"
+ "<col column-id='mail' sortable>"
+ "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th>"
+ "<th plain-text column-ids='mail'>Mail</th></tr></thead>"
+ "<tfoot><tr><td plain-text column-ids='column0'>%s</td>"
+ "<td colspan='2' column-ids='id,mail'>%s</td></tr></tfoot>"
+ "</table></%s>",
getComponentTag(), footerRowText1, footerRowText2,
getComponentTag());

testRead(design, grid);
testWrite(design, grid);
@@ -158,9 +164,10 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
Grid<Person> grid = new Grid<>();

String secondColumnId = "id";
Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
Column<Person, String> column2 = grid.addColumn(secondColumnId,
Person::getLastName);
Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
.setCaption("First Name");
Column<Person, String> column2 = grid.addColumn(Person::getLastName)
.setId(secondColumnId).setCaption("Id");

String caption = "test-caption";
column1.setCaption(caption);
@@ -189,10 +196,10 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {

String design = String.format(
"<%s><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable='%s' editable resizable='%s' hidable hidden>"
+ "<col column-id='column0' sortable='%s' editable resizable='%s' hidable hidden>"
+ "<col column-id='id' sortable hiding-toggle-caption='%s' width='%s' min-width='%s' max-width='%s' expand='%s'>"
+ "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>%s</th>"
+ "<tr default><th plain-text column-ids='column0'>%s</th>"
+ "<th plain-text column-ids='id'>%s</th>"
+ "</tr></thead>" + "</table></%s>",
getComponentTag(), sortable, resizable, hidingToggleCaption,
@@ -207,22 +214,24 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
public void headerFooterSerialization() {
Grid<Person> grid = new Grid<>();

Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
Column<Person, String> column2 = grid.addColumn("id",
Person::getLastName);
Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
.setCaption("First Name");
Column<Person, String> column2 = grid.addColumn(Person::getLastName)
.setId("id").setCaption("Id");

FooterRow footerRow = grid.addFooterRowAt(0);
footerRow.getCell(column1).setText("x");
footerRow.getCell(column2).setHtml("y");

String design = String.format("<%s><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
+ "<col column-id='id' sortable></colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead><tbody></tbody>"
+ "<tfoot><tr><td plain-text column-ids='generatedColumn0'>x</td>"
+ "<td column-ids='id'>y</td></tr></tfoot>" + "</table></%s>",
String design = String.format(
"<%s><table><colgroup>" + "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable></colgroup><thead>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead><tbody></tbody>"
+ "<tfoot><tr><td plain-text column-ids='column0'>x</td>"
+ "<td column-ids='id'>y</td></tr></tfoot>"
+ "</table></%s>",
getComponentTag(), getComponentTag());

testRead(design, grid);
@@ -238,14 +247,13 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
Person person2 = createPerson("name", "last-name");
grid.setItems(person1, person2);

grid.addColumn(Person::getFirstName);
grid.addColumn("id", Person::getLastName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setId("id").setCaption("Id");

String design = String.format(
"<%s><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
"<%s><table><colgroup>" + "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable></colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead><tbody>"
+ "<tr item='%s'><td>%s</td><td>%s</td></tr>"
@@ -281,8 +289,8 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
Person person3 = createPerson("foo", "last-name");
grid.setItems(person1, person2, person3);

grid.addColumn(Person::getFirstName);
grid.addColumn("id", Person::getLastName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setId("id").setCaption("Id");

Multi<Person> model = (Multi<Person>) grid
.setSelectionMode(SelectionMode.MULTI);
@@ -290,9 +298,9 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {

String design = String.format(
"<%s selection-mode='multi'><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
+ "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable></colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead><tbody>"
+ "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
@@ -318,18 +326,17 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
Person person2 = createPerson("name", "last-name");
grid.setItems(person1, person2);

grid.addColumn(Person::getFirstName);
grid.addColumn("id", Person::getLastName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setId("id").setCaption("Id");

Single<Person> model = (Single<Person>) grid
.setSelectionMode(SelectionMode.SINGLE);
model.select(person2);

String design = String.format(
"<%s><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
"<%s><table><colgroup>" + "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable></colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead><tbody>"
+ "<tr item='%s'><td>%s</td><td>%s</td></tr>"
@@ -353,16 +360,16 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
Person person2 = createPerson("name", "last-name");
grid.setItems(person1, person2);

grid.addColumn(Person::getFirstName);
grid.addColumn("id", Person::getLastName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setId("id").setCaption("Id");

grid.setSelectionMode(SelectionMode.MULTI);
grid.asMultiSelect().setReadOnly(true);

String formatString = "<%s %s selection-allowed><table><colgroup>"
+ "<col column-id='generatedColumn0' sortable>"
+ "<col column-id='column0' sortable>"
+ "<col column-id='id' sortable>" + "</colgroup><thead>"
+ "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ "<tr default><th plain-text column-ids='column0'>First Name</th>"
+ "<th plain-text column-ids='id'>Id</th></tr>"
+ "</thead><tbody>"
+ "<tr item='%s'><td>%s</td><td>%s</td></tr>"
@@ -394,7 +401,8 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
@Test
public void testComponentInGridHeader() {
Grid<Person> grid = new Grid<>();
Column<Person, String> column = grid.addColumn(Person::getFirstName);
Column<Person, String> column = grid.addColumn(Person::getFirstName)
.setCaption("First Name");

String html = "<b>Foo</b>";
Label component = new Label(html);
@@ -403,16 +411,15 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
//@formatter:off
String design = String.format( "<%s><table>"
+ "<colgroup>"
+ " <col sortable column-id='generatedColumn0'>"
+ " <col sortable column-id='column0'>"
+ "</colgroup>"
+ "<thead>"
+ "<tr default><th column-ids='generatedColumn0'><vaadin-label>%s</vaadin-label></th></tr>"
+ "<tr default><th column-ids='column0'><vaadin-label>%s</vaadin-label></th></tr>"
+ "</thead>"
+ "</table></%s>", getComponentTag(), html, getComponentTag());
//@formatter:on

grid.getDefaultHeaderRow().getCell(column.getId())
.setComponent(component);
grid.getDefaultHeaderRow().getCell(column).setComponent(component);

testRead(design, grid, true);
testWrite(design, grid);
@@ -421,7 +428,8 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
@Test
public void testComponentInGridFooter() {
Grid<Person> grid = new Grid<>();
Column<Person, String> column = grid.addColumn(Person::getFirstName);
Column<Person, String> column = grid.addColumn(Person::getFirstName)
.setCaption("First Name");

String html = "<b>Foo</b>";
Label component = new Label(html);
@@ -433,11 +441,11 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
//@formatter:off
String design = String.format( "<%s><table>"
+ "<colgroup>"
+ " <col sortable column-id='generatedColumn0'>"
+ " <col sortable column-id='column0'>"
+ "</colgroup>"
+ "<thead>"
+"<tfoot>"
+ "<tr><td column-ids='generatedColumn0'><vaadin-label>%s</vaadin-label></td></tr>"
+ "<tr><td column-ids='column0'><vaadin-label>%s</vaadin-label></td></tr>"
+ "</tfoot>"
+ "</table>"
+ "</%s>", getComponentTag(), html, getComponentTag());
@@ -452,14 +460,14 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
//@formatter:off
String design = "<vaadin-grid><table>"
+ "<colgroup>"
+ " <col sortable column-id='generatedColumn0'>"
+ " <col sortable column-id='column0'>"
+ "</colgroup>"
+ "<thead />"
+ "</table>"
+ "</vaadin-grid>";
//@formatter:on
Grid<Person> grid = new Grid<>();
grid.addColumn(Person::getFirstName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.removeHeaderRow(grid.getDefaultHeaderRow());

testWrite(design, grid);
@@ -509,7 +517,7 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
+ "<tr><td %s column-ids='%s'>&gt; Test</td></tr>"
+ "</tfoot>"
+ "<tbody />"
+ "</table></%s>",
+ "</table></%s>",
getComponentTag() , id, plainText, id, plainText, id, getComponentTag());
//@formatter:on

@@ -531,8 +539,8 @@ public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
Assert.assertEquals(expected, actualFooter);

grid = new Grid<>();
Column<Person, String> column = grid.addColumn(id,
Person::getFirstName);
Column<Person, String> column = grid.addColumn(Person::getFirstName)
.setId(id);
HeaderRow header = grid.addHeaderRowAt(0);
FooterRow footer = grid.addFooterRowAt(0);
grid.removeHeaderRow(grid.getDefaultHeaderRow());

+ 7
- 5
server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java View File

@@ -1,12 +1,12 @@
/*
* 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
@@ -35,8 +35,10 @@ public class GridDefaultHeaderTest {
public void setUp() {
grid = new Grid<>();

column1 = grid.addColumn("First", ValueProvider.identity());
column2 = grid.addColumn("Second", ValueProvider.identity());
column1 = grid.addColumn(ValueProvider.identity()).setId("First")
.setCaption("First");
column2 = grid.addColumn(ValueProvider.identity()).setId("Second")
.setCaption("Second");
}

@Test

+ 6
- 4
server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java View File

@@ -139,16 +139,18 @@ public class GridHeaderFooterTest {

@Test
public void addColumn_headerCellAdded() {
Column<?, ?> column = grid.addColumn("Col",
ValueProvider.identity());

Column<?, ?> column = grid.addColumn(ValueProvider.identity())
.setId("Col");

assertNotNull(grid.getHeaderRow(0).getCell(column));
}

@Test(expected = IllegalArgumentException.class)
public void removeColumn_headerCellRemoved() {
Column<String, ?> column = grid.addColumn("Col",
ValueProvider.identity());

Column<String, ?> column = grid.addColumn(ValueProvider.identity())
.setId("Col");
grid.removeColumn(column);

grid.getHeaderRow(0).getCell(column);

+ 4
- 17
server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java View File

@@ -30,9 +30,10 @@ public class GridTest {
@Before
public void setUp() {
grid = new Grid<>();
grid.addColumn("foo", ValueProvider.identity());

grid.addColumn(ValueProvider.identity()).setId("foo");
grid.addColumn(String::length, new NumberRenderer());
grid.addColumn("randomColumnId", ValueProvider.identity());
grid.addColumn(ValueProvider.identity()).setId("randomColumnId");
}

@Test
@@ -73,23 +74,9 @@ public class GridTest {
grid.getHeaderRow(0).getCell("foo").getText());
}

@Test
public void testGridColumnGeneratedIdentifier() {
assertEquals("Unexpected caption on a generated Column",
"Generated Column0",
grid.getColumn("generatedColumn0").getCaption());
}

@Test
public void testGridColumnCaptionFromIdentifier() {
assertEquals("Unexpected caption on a generated Column",
"Random Column Id",
grid.getColumn("randomColumnId").getCaption());
}

@Test(expected = IllegalArgumentException.class)
public void testGridMultipleColumnsWithSameIdentifier() {
grid.addColumn("foo", t -> t);
grid.addColumn(t -> t).setId("foo");
}

@Test

+ 1
- 1
shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java View File

@@ -20,7 +20,7 @@ import com.vaadin.shared.Connector;
public class ColumnState extends AbstractGridExtensionState {

public String caption;
public String id;
public String internalId;
public boolean sortable;
public boolean editable = false;


+ 16
- 15
shared/src/main/java/com/vaadin/shared/ui/grid/GridServerRpc.java View File

@@ -23,7 +23,7 @@ import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.grid.GridConstants.Section;

/**
* Client-to-server RPC interface for the Grid component
* Client-to-server RPC interface for the Grid component.
*
* @since 7.4
* @author Vaadin Ltd
@@ -38,12 +38,13 @@ public interface GridServerRpc extends ServerRpc {
*
* @param rowKey
* a key identifying the clicked item
* @param columnId
* column id identifying the clicked property
* @param columnInternalId
* column internal id identifying the clicked property
* @param details
* mouse event details
*/
void itemClick(String rowKey, String columnId, MouseEventDetails details);
void itemClick(String rowKey, String columnInternalId,
MouseEventDetails details);

/**
* Informs the server that a context click has happened inside of Grid.
@@ -53,14 +54,14 @@ public interface GridServerRpc extends ServerRpc {
* index of clicked row in Grid section
* @param rowKey
* a key identifying the clicked item
* @param columnId
* column id identifying the clicked property
* @param columnInternalId
* column internal id identifying the clicked property
* @param section
* grid section (header, footer, body)
* @param details
* mouse event details
*/
void contextClick(int rowIndex, String rowKey, String columnId,
void contextClick(int rowIndex, String rowKey, String columnInternalId,
Section section, MouseEventDetails details);

/**
@@ -68,9 +69,9 @@ public interface GridServerRpc extends ServerRpc {
*
* @since 7.5.0
* @param newColumnOrder
* a list of column ids in the new order
* a list of column internal ids in the new order
* @param oldColumnOrder
* a list of column ids in order before the change
* a list of column internal ids in order before the change
*/
void columnsReordered(List<String> newColumnOrder,
List<String> oldColumnOrder);
@@ -79,21 +80,21 @@ public interface GridServerRpc extends ServerRpc {
* Informs the server that a column's visibility has been changed.
*
* @since 7.5.0
* @param id
* the id of the column
* @param columnInternalId
* the internal id of the column
* @param hidden
* <code>true</code> if hidden, <code>false</code> if unhidden
*/
void columnVisibilityChanged(String id, boolean hidden);
void columnVisibilityChanged(String columnInternalId, boolean hidden);

/**
* Informs the server that a column has been resized by the user.
*
* @since 7.6
* @param id
* the id of the column
* @param columnInternalId
* the internal id of the column
* @param pixels
* the new width of the column in pixels
*/
void columnResized(String id, double pixels);
void columnResized(String columnInternalId, double pixels);
}

+ 2
- 1
uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java View File

@@ -16,7 +16,8 @@ public class GridApplyFilterWhenScrolledDown extends AbstractTestUI {
protected void setup(VaadinRequest request) {
Grid<String> grid = new Grid<>();

grid.addColumn("Name", ValueProvider.identity());
grid.addColumn(ValueProvider.identity()).setId("Name")
.setCaption("Name");

List<String> data = new ArrayList<>();
for (int i = 0; i < 1000; i++) {

+ 7
- 5
uitest/src/main/java/com/vaadin/tests/components/grid/GridClickableRenderers.java View File

@@ -32,18 +32,20 @@ public class GridClickableRenderers extends AbstractReindeerTestUI {
Label checkBoxValueLabel = new Label("checkbox click label");
Grid<TestPOJO> grid = new Grid<>();

grid.addColumn("images", pojo -> new ExternalResource(pojo.imageUrl),
new ImageRenderer<>());
grid.addColumn("buttons", pojo -> pojo.buttonText,
grid.addColumn(pojo -> new ExternalResource(pojo.imageUrl),
new ImageRenderer<>()).setId("images").setCaption("Images");
grid.addColumn(pojo -> pojo.buttonText,
new ButtonRenderer<>(event -> valueDisplayLabel
.setValue(event.getItem().testText + " clicked")));
.setValue(event.getItem().testText + " clicked")))
.setId("buttons").setCaption("Buttons");

CheckBoxRenderer<TestPOJO> checkBoxRenderer = new CheckBoxRenderer<>(
pojo -> pojo.truthValue,
(pojo, newTruthValue) -> pojo.truthValue = newTruthValue);
checkBoxRenderer.addClickListener(click -> checkBoxValueLabel.setValue(
click.getItem().testText + " " + click.getItem().truthValue));
grid.addColumn("checkboxes", pojo -> pojo.truthValue, checkBoxRenderer);
grid.addColumn(pojo -> pojo.truthValue, checkBoxRenderer)
.setId("checkboxes").setCaption("Checkboxes");

grid.setItems(new TestPOJO("first row", "", "button 1 text", true),
new TestPOJO("second row", "", "button 2 text", false));

+ 7
- 6
uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java View File

@@ -16,14 +16,15 @@ public class GridColumnHiding extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
Grid<Person> grid = new Grid<>();
Column<Person, String> nameColumn = grid
.addColumn("Name", Person::getFirstName).setHidable(true);
Column<Person, String> nameColumn = grid.addColumn(Person::getFirstName)
.setHidable(true).setCaption("Name");
Column<Person, Number> ageColumn = grid
.addColumn("Age", Person::getAge, new NumberRenderer())
.addColumn(Person::getAge, new NumberRenderer())
.setHidable(true)
.setHidingToggleCaption("custom age column caption");
Column<Person, String> emailColumn = grid.addColumn("Email",
Person::getEmail);
.setHidingToggleCaption("custom age column caption")
.setCaption("Age");
Column<Person, String> emailColumn = grid.addColumn(Person::getEmail)
.setCaption("Email");

Button toggleNameColumn = new Button("server side toggle name column");
Button toggleAgeColumn = new Button("server side toggle age column");

+ 5
- 4
uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnResizing.java View File

@@ -20,10 +20,11 @@ public class GridColumnResizing extends AbstractReindeerTestUI {
TextField input = new TextField();
Label isResizedLabel = new Label("not resized");
Grid<Person> grid = new Grid<>();
Column<Person, String> nameColumn = grid.addColumn("Name",
Person::getFirstName);
Column<Person, Number> ageColumn = grid.addColumn("Age", Person::getAge,
new NumberRenderer());
Column<Person, String> nameColumn = grid.addColumn(Person::getFirstName)
.setCaption("Name");
Column<Person, Number> ageColumn = grid
.addColumn(Person::getAge, new NumberRenderer())
.setCaption("Age");
grid.addColumnResizeListener(event -> {
if (event.isUserOriginated()) {
isResizedLabel.setValue("client resized");

+ 2
- 2
uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java View File

@@ -51,8 +51,8 @@ public class InitiallyDisabledGrid extends UI {
Grid<Person> grid = new Grid<>();
grid.setSizeFull();
grid.setItems(people);
grid.addColumn("firstName", Person::getFirstName);
grid.addColumn("lastNAme", Person::getLastName);
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setCaption("Last Name");

grid.setEnabled(false);


+ 5
- 4
uitest/src/main/java/com/vaadin/tests/components/grid/JavaScriptRenderers.java View File

@@ -94,10 +94,11 @@ public class JavaScriptRenderers extends AbstractReindeerTestUI {

Grid<ItemBean> grid = new Grid<>();

grid.addColumn("id", item -> item.getId().toString());
grid.addColumn("bean", ItemBean::getBean, new MyBeanJSRenderer());
grid.addColumn("string", ItemBean::getString,
new JavaScriptStringRenderer());
grid.addColumn(item -> item.getId().toString()).setCaption("Id");
grid.addColumn(ItemBean::getBean, new MyBeanJSRenderer())
.setCaption("Bean");
grid.addColumn(ItemBean::getString, new JavaScriptStringRenderer())
.setCaption("String");

grid.setItems(items);


+ 2
- 1
uitest/src/main/java/com/vaadin/tests/components/grid/basics/RefreshDataProvider.java View File

@@ -39,7 +39,8 @@ public class RefreshDataProvider extends AbstractReindeerTestUI {
grid.setDataProvider(dataProvider);

grid.setDataProvider(dataProvider);
grid.addColumn("Coordinates", DataObject::getCoordinates);
grid.addColumn(DataObject::getCoordinates).setCaption("Coordinates")
.setId("Coordinates");
addComponent(grid);

Button update = new Button("Update data",

+ 15
- 13
uitest/src/main/java/com/vaadin/tests/contextclick/GridContextClick.java View File

@@ -33,19 +33,21 @@ public class GridContextClick extends
protected Grid<Person> createTestComponent() {
Grid<Person> grid = new Grid<>();
grid.setItems(PersonContainer.createTestData());
grid.addColumn("Address",
person -> String.valueOf(person.getAddress()));
grid.addColumn("Email", person -> String.valueOf(person.getEmail()));
grid.addColumn("First Name",
person -> String.valueOf(person.getFirstName()));
grid.addColumn("Last Name",
person -> String.valueOf(person.getLastName()));
grid.addColumn("Phone Number",
person -> String.valueOf(person.getPhoneNumber()));
grid.addColumn("Street Address", person -> String
.valueOf(person.getAddress().getStreetAddress()));
grid.addColumn("City",
person -> String.valueOf(person.getAddress().getCity()));
grid.addColumn(person -> String.valueOf(person.getAddress()))
.setCaption("Address");
grid.addColumn(person -> String.valueOf(person.getEmail()))
.setCaption("Email");
grid.addColumn(person -> String.valueOf(person.getFirstName()))
.setCaption("First Name");
grid.addColumn(person -> String.valueOf(person.getLastName()))
.setCaption("Last Name");
grid.addColumn(person -> String.valueOf(person.getPhoneNumber()))
.setCaption("Phone Number");
grid.addColumn(person -> String
.valueOf(person.getAddress().getStreetAddress()))
.setCaption("Street Address");
grid.addColumn(person -> String.valueOf(person.getAddress().getCity()))
.setCaption("City");

// grid.setFooterVisible(true);
// grid.appendFooterRow();

+ 10
- 10
uitest/src/main/java/com/vaadin/tests/performance/GridMemory.java View File

@@ -46,16 +46,16 @@ public class GridMemory extends AbstractBeansMemoryTest<Grid<Person>> {
@Override
protected Grid<Person> createComponent() {
Grid<Person> grid = new Grid<>();
grid.addColumn("First Name", Person::getFirstName);
grid.addColumn("Last Name", Person::getLastName);
grid.addColumn("Street",
person -> Optional.ofNullable(person.getAddress())
.map(Address::getStreetAddress).orElse(null));
grid.addColumn("Zip", person -> Optional.ofNullable(person.getAddress())
.map(Address::getPostalCode).map(Object::toString).orElse(""));
grid.addColumn("City",
person -> Optional.ofNullable(person.getAddress())
.map(Address::getCity).orElse(null));
grid.addColumn(Person::getFirstName).setCaption("First Name");
grid.addColumn(Person::getLastName).setCaption("Last Name");
grid.addColumn(person -> Optional.ofNullable(person.getAddress())
.map(Address::getStreetAddress).orElse(null))
.setCaption("Street");
grid.addColumn(person -> Optional.ofNullable(person.getAddress())
.map(Address::getPostalCode).map(Object::toString).orElse(""))
.setCaption("Zip");
grid.addColumn(person -> Optional.ofNullable(person.getAddress())
.map(Address::getCity).orElse(null)).setCaption("City");
return grid;
}


Loading…
Cancel
Save