Selaa lähdekoodia

Add server-side CellStyleGenerator (#13334)

Change-Id: Id12f1135673d93fddd0a59d26b1c546a0ef0ee1d
tags/7.4.0.beta1
Leif Åstrand 9 vuotta sitten
vanhempi
commit
ca061119ca

+ 39
- 0
client/src/com/vaadin/client/ui/grid/GridConnector.java Näytä tiedosto

@@ -41,6 +41,7 @@ import com.vaadin.client.data.RpcDataSourceConnector.RpcDataSource;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.AbstractHasComponentsConnector;
import com.vaadin.client.ui.SimpleManagedLayout;
import com.vaadin.client.ui.grid.Grid.CellStyleGenerator;
import com.vaadin.client.ui.grid.GridHeader.HeaderRow;
import com.vaadin.client.ui.grid.renderers.AbstractRendererConnector;
import com.vaadin.client.ui.grid.selection.AbstractRowHandleSelectionModel;
@@ -81,6 +82,35 @@ import com.vaadin.shared.ui.grid.SortDirection;
public class GridConnector extends AbstractHasComponentsConnector implements
SimpleManagedLayout {

private static final class CustomCellStyleGenerator implements
CellStyleGenerator<JSONObject> {
@Override
public String getStyle(Grid<JSONObject> grid, JSONObject row,
int rowIndex, GridColumn<?, JSONObject> column, int columnIndex) {
if (column == null) {
JSONValue styleValue = row.get(GridState.JSONKEY_ROWSTYLE);
if (styleValue != null) {
return styleValue.isString().stringValue();
} else {
return null;
}
} else {
JSONValue cellstyles = row.get(GridState.JSONKEY_CELLSTYLES);
if (cellstyles == null) {
return null;
}

CustomGridColumn c = (CustomGridColumn) column;
JSONValue styleValue = cellstyles.isObject().get(c.id);
if (styleValue != null) {
return styleValue.isString().stringValue();
} else {
return null;
}
}
}
}

/**
* Custom implementation of the custom grid column using a JSONObject to
* represent the cell value and String as a column type.
@@ -644,6 +674,15 @@ public class GridConnector extends AbstractHasComponentsConnector implements
}
}

@OnStateChange("hasCellStyleGenerator")
private void onCellStyleGeneratorChange() {
if (getState().hasCellStyleGenerator) {
getWidget().setCellStyleGenerator(new CustomCellStyleGenerator());
} else {
getWidget().setCellStyleGenerator(null);
}
}

@OnStateChange("selectedKeys")
private void updateSelectionFromState() {
boolean changed = false;

+ 50
- 1
server/src/com/vaadin/data/RpcDataProviderExtension.java Näytä tiedosto

@@ -47,6 +47,7 @@ import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.shared.ui.grid.GridState;
import com.vaadin.shared.ui.grid.Range;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.CellStyleGenerator;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.components.grid.Renderer;

@@ -718,7 +719,6 @@ public class RpcDataProviderExtension extends AbstractExtension {

Grid grid = getGrid();

int i = 0;
for (Object propertyId : propertyIds) {
Column column = grid.getColumn(propertyId);

@@ -733,9 +733,42 @@ public class RpcDataProviderExtension extends AbstractExtension {
final JsonObject rowObject = Json.createObject();
rowObject.put(GridState.JSONKEY_DATA, rowData);
rowObject.put(GridState.JSONKEY_ROWKEY, keyMapper.getKey(itemId));

CellStyleGenerator cellStyleGenerator = grid.getCellStyleGenerator();
if (cellStyleGenerator != null) {
setGeneratedStyles(cellStyleGenerator, rowObject, propertyIds,
itemId);
}

return rowObject;
}

private void setGeneratedStyles(CellStyleGenerator generator,
JsonObject rowObject, Collection<?> propertyIds, Object itemId) {
Grid grid = getGrid();

JsonObject cellStyles = null;
for (Object propertyId : propertyIds) {
String style = generator.getStyle(grid, itemId, propertyId);
if (style != null) {
if (cellStyles == null) {
cellStyles = Json.createObject();
}

String columnKey = columnKeys.key(propertyId);
cellStyles.put(columnKey, style);
}
}
if (cellStyles != null) {
rowObject.put(GridState.JSONKEY_CELLSTYLES, cellStyles);
}

String rowStyle = generator.getStyle(grid, itemId, null);
if (rowStyle != null) {
rowObject.put(GridState.JSONKEY_ROWSTYLE, rowStyle);
}
}

@Override
protected DataProviderState getState() {
return (DataProviderState) super.getState();
@@ -813,6 +846,22 @@ public class RpcDataProviderExtension extends AbstractExtension {
rpc.setRowData(index, rowArray.toJson());
}

/**
* Pushes a new version of all the rows in the active cache range.
*/
public void refreshCache() {
if (!clientInitialized) {
return;
}

int firstRow = activeRowHandler.activeRange.getStart();
int numberOfRows = activeRowHandler.activeRange.length();

List<?> itemIds = RpcDataProviderExtension.this.container.getItemIds(
firstRow, numberOfRows);
pushRows(firstRow, itemIds);
}

@Override
public void setParent(ClientConnector parent) {
super.setParent(parent);

+ 59
- 0
server/src/com/vaadin/ui/Grid.java Näytä tiedosto

@@ -200,6 +200,37 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
protected abstract SelectionModel createModel();
}

/**
* Callback interface for generating custom style names for data rows and
* cells.
*
* @see Grid#setCellStyleGenerator(CellStyleGenerator)
*/
public interface CellStyleGenerator extends Serializable {

/**
* Called by Grid to generate a style name for a row or cell element.
* Row styles are generated when the column parameter is
* <code>null</code>, otherwise a cell style is generated.
* <p>
* The returned style name is prefixed so that the actual style for
* cells will be <tt>v-grid-cell-content-[style name]</tt>, and the row
* style will be <tt>v-grid-row-[style name]</tt>.
*
* @param grid
* the source grid
* @param itemId
* the itemId of the target row
* @param propertyId
* the propertyId of the target cell, <code>null</code> when
* getting row style
* @return the style name to add to this cell or row element, or
* <code>null</code> to not set any style
*/
public abstract String getStyle(Grid grid, Object itemId,
Object propertyId);
}

/**
* Abstract base class for Grid header and footer sections.
*
@@ -1941,6 +1972,8 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,

private EditorRow editorRow;

private CellStyleGenerator cellStyleGenerator;

/**
* <code>true</code> if Grid is using the internal IndexedContainer created
* in Grid() constructor, or <code>false</code> if the user has set their
@@ -3551,4 +3584,30 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
EditorRowClientRpc getEditorRowRpc() {
return getRpcProxy(EditorRowClientRpc.class);
}

/**
* Sets the cell style generator that is used for generating styles for rows
* and cells.
*
* @param cellStyleGenerator
* the cell style generator to set, or <code>null</code> to
* remove a previously set generator
*/
public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator) {
this.cellStyleGenerator = cellStyleGenerator;
getState().hasCellStyleGenerator = (cellStyleGenerator != null);

datasourceExtension.refreshCache();
}

/**
* Gets the cell style generator that is used for generating styles for rows
* and cells.
*
* @return the cell style generator, or <code>null</code> if no generator is
* set
*/
public CellStyleGenerator getCellStyleGenerator() {
return cellStyleGenerator;
}
}

+ 17
- 0
shared/src/com/vaadin/shared/ui/grid/GridState.java Näytä tiedosto

@@ -87,6 +87,20 @@ public class GridState extends AbstractComponentState {
*/
public static final String JSONKEY_ROWKEY = "k";

/**
* The key in which a row's generated style can be found
*
* @see com.vaadin.shared.data.DataProviderRpc#setRowData(int, String)
*/
public static final String JSONKEY_ROWSTYLE = "rs";

/**
* The key in which a generated styles for a row's cells can be found
*
* @see com.vaadin.shared.data.DataProviderRpc#setRowData(int, String)
*/
public static final String JSONKEY_CELLSTYLES = "cs";

/**
* Columns in grid.
*/
@@ -129,4 +143,7 @@ public class GridState extends AbstractComponentState {

/** The enabled state of the editor row */
public boolean editorRowEnabled = false;

/** Whether row data might contain generated styles */
public boolean hasCellStyleGenerator;
}

+ 54
- 1
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java Näytä tiedosto

@@ -38,8 +38,9 @@ import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.FooterCell;
import com.vaadin.ui.Grid.CellStyleGenerator;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.FooterCell;
import com.vaadin.ui.Grid.HeaderCell;
import com.vaadin.ui.Grid.HeaderRow;
import com.vaadin.ui.Grid.SelectionMode;
@@ -285,6 +286,58 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> {
}
}
});

LinkedHashMap<String, CellStyleGenerator> styleGenerators = new LinkedHashMap<String, CellStyleGenerator>();
styleGenerators.put("None", null);
styleGenerators.put("Row only", new CellStyleGenerator() {
@Override
public String getStyle(Grid grid, Object itemId, Object propertyId) {
if (propertyId == null) {
return "row" + itemId;
} else {
return null;
}
}
});
styleGenerators.put("Cell only", new CellStyleGenerator() {
@Override
public String getStyle(Grid grid, Object itemId, Object propertyId) {
if (propertyId == null) {
return null;
} else {
return propertyId.toString().replace(' ', '-');
}
}
});
styleGenerators.put("Combined", new CellStyleGenerator() {
@Override
public String getStyle(Grid grid, Object itemId, Object propertyId) {
int rowIndex = ((Integer) itemId).intValue();
if (propertyId == null) {
if (rowIndex % 4 == 0) {
return null;
} else {
return "row" + itemId;
}
} else {
if (rowIndex % 4 == 1) {
return null;
} else if (rowIndex % 4 == 3
&& "Column 1".equals(propertyId)) {
return null;
}
return propertyId.toString().replace(' ', '_');
}
}
});
createSelectAction("Style generator", "State", styleGenerators, "None",
new Command<Grid, CellStyleGenerator>() {
@Override
public void execute(Grid grid,
CellStyleGenerator generator, Object data) {
grid.setCellStyleGenerator(generator);
}
});
}

protected void createHeaderActions() {

+ 108
- 0
uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellStyleGeneratorTest.java Näytä tiedosto

@@ -0,0 +1,108 @@
/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.grid.basicfeatures.server;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.tests.components.grid.GridElement.GridCellElement;
import com.vaadin.tests.components.grid.GridElement.GridRowElement;
import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest;

public class GridCellStyleGeneratorTest extends GridBasicFeaturesTest {
@Test
public void testStyleNameGeneratorScrolling() throws Exception {
openTestURL();

selectStyleNameGenerator("Combined");

GridRowElement row2 = getGridElement().getRow(2);
GridCellElement cell3_2 = getGridElement().getCell(3, 2);

Assert.assertTrue(row2.getAttribute("class")
.contains("v-grid-row-row2"));
Assert.assertTrue(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column_2"));

// Scroll down and verify that the old elements don't have the
// stylename any more

// Carefully chosen offset to hit an index % 4 without cell style
getGridElement().getRow(352);

Assert.assertFalse(row2.getAttribute("class").contains(
"v-grid-row-row2"));
Assert.assertFalse(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column_2"));
}

@Test
public void testDisableStyleNameGenerator() throws Exception {
openTestURL();

selectStyleNameGenerator("Combined");

// Just verify that change was effective
GridRowElement row2 = getGridElement().getRow(2);
GridCellElement cell3_2 = getGridElement().getCell(3, 2);

Assert.assertTrue(row2.getAttribute("class")
.contains("v-grid-row-row2"));
Assert.assertTrue(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column_2"));

// Disable the generator and check again
selectStyleNameGenerator("None");

Assert.assertFalse(row2.getAttribute("class").contains(
"v-grid-row-row2"));
Assert.assertFalse(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column_2"));
}

@Test
public void testChangeStyleNameGenerator() throws Exception {
openTestURL();

selectStyleNameGenerator("Combined");

// Just verify that change was effective
GridRowElement row2 = getGridElement().getRow(2);
GridCellElement cell3_2 = getGridElement().getCell(3, 2);

Assert.assertTrue(row2.getAttribute("class")
.contains("v-grid-row-row2"));
Assert.assertTrue(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column_2"));

// Change the generator and check again
selectStyleNameGenerator("Cell only");

// Old styles removed?
Assert.assertFalse(row2.getAttribute("class").contains(
"v-grid-row-row2"));
Assert.assertFalse(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column_2"));

// New style present?
Assert.assertTrue(cell3_2.getAttribute("class").contains(
"v-grid-cell-content-Column-2"));
}

private void selectStyleNameGenerator(String name) {
selectMenuPath("Component", "State", "Style generator", name);
}
}

Loading…
Peruuta
Tallenna