aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2016-02-11 10:15:15 +0100
committerVaadin Code Review <review@vaadin.com>2016-03-14 09:07:39 +0000
commit888fec0669c3a34ffaedb883029b37b10b00399a (patch)
treed9ad6aebdb696e47414bf9494ce08b0900b64014
parentacab3d3c0c8eda303a8aa331ba5b17d38164542a (diff)
downloadvaadin-framework-888fec0669c3a34ffaedb883029b37b10b00399a.tar.gz
vaadin-framework-888fec0669c3a34ffaedb883029b37b10b00399a.zip
Initial import of TypedGrid component
This patch introduces a generics version of Grid. Change-Id: I0777a0468ccb5f38e266aa0f33ceb8d0324d72dd
-rw-r--r--client/src/com/vaadin/client/connectors/proto/AbstractTypedGridExtensionConnector.java33
-rw-r--r--client/src/com/vaadin/client/connectors/proto/TypedGridColumnConnector.java62
-rw-r--r--client/src/com/vaadin/client/connectors/proto/TypedGridConnector.java125
-rw-r--r--server/src/com/vaadin/ui/proto/Column.java67
-rw-r--r--server/src/com/vaadin/ui/proto/TypedGrid.java275
-rw-r--r--server/src/com/vaadin/ui/proto/ValueProvider.java22
-rw-r--r--shared/src/com/vaadin/shared/ui/proto/TypedGridClientRpc.java24
-rw-r--r--shared/src/com/vaadin/shared/ui/proto/TypedGridColumnState.java24
-rw-r--r--shared/src/com/vaadin/shared/ui/proto/TypedGridServerRpc.java23
-rw-r--r--shared/src/com/vaadin/shared/ui/proto/TypedGridState.java21
-rw-r--r--uitest/src/com/vaadin/tests/proto/TypedGridUI.java45
11 files changed, 721 insertions, 0 deletions
diff --git a/client/src/com/vaadin/client/connectors/proto/AbstractTypedGridExtensionConnector.java b/client/src/com/vaadin/client/connectors/proto/AbstractTypedGridExtensionConnector.java
new file mode 100644
index 0000000000..4c590fbb5d
--- /dev/null
+++ b/client/src/com/vaadin/client/connectors/proto/AbstractTypedGridExtensionConnector.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.connectors.proto;
+
+import com.vaadin.client.extensions.AbstractExtensionConnector;
+
+/**
+ * Base connector class for AbstractTypedGridExtensions. This class provides
+ * helpers to ease the use of TypedGrid client-side in extension connectors.
+ *
+ * @since
+ */
+public abstract class AbstractTypedGridExtensionConnector extends
+ AbstractExtensionConnector {
+
+ @Override
+ public TypedGridConnector getParent() {
+ return (TypedGridConnector) super.getParent();
+ }
+}
diff --git a/client/src/com/vaadin/client/connectors/proto/TypedGridColumnConnector.java b/client/src/com/vaadin/client/connectors/proto/TypedGridColumnConnector.java
new file mode 100644
index 0000000000..00a7da8925
--- /dev/null
+++ b/client/src/com/vaadin/client/connectors/proto/TypedGridColumnConnector.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.connectors.proto;
+
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.widgets.Grid.Column;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.shared.ui.proto.TypedGridColumnState;
+
+import elemental.json.JsonObject;
+
+/**
+ * Connector implementation for TypedGrid Columns.
+ *
+ * @since
+ */
+@Connect(com.vaadin.ui.proto.Column.class)
+public class TypedGridColumnConnector extends
+ AbstractTypedGridExtensionConnector {
+
+ /* This is stored so it can be used in onUnregister */
+ private TypedGridConnector parent;
+
+ @Override
+ protected void extend(ServerConnector target) {
+ parent = getParent();
+ parent.addColumn(getState().id, new Column<String, JsonObject>() {
+ @Override
+ public String getValue(JsonObject row) {
+ return row.getObject(GridState.JSONKEY_DATA).getString(
+ getState().id);
+ }
+ });
+ }
+
+ @Override
+ public void onUnregister() {
+ super.onUnregister();
+
+ parent.removeColumn(getState().id);
+ }
+
+ @Override
+ public TypedGridColumnState getState() {
+ return (TypedGridColumnState) super.getState();
+ }
+
+}
diff --git a/client/src/com/vaadin/client/connectors/proto/TypedGridConnector.java b/client/src/com/vaadin/client/connectors/proto/TypedGridConnector.java
new file mode 100644
index 0000000000..41f6cfccd1
--- /dev/null
+++ b/client/src/com/vaadin/client/connectors/proto/TypedGridConnector.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.connectors.proto;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.vaadin.client.connectors.GridConnector;
+import com.vaadin.client.data.DataSource;
+import com.vaadin.client.data.HasDataSource;
+import com.vaadin.client.ui.AbstractComponentConnector;
+import com.vaadin.client.ui.SimpleManagedLayout;
+import com.vaadin.client.widget.grid.selection.SelectionEvent;
+import com.vaadin.client.widget.grid.selection.SelectionHandler;
+import com.vaadin.client.widgets.Grid;
+import com.vaadin.client.widgets.Grid.Column;
+import com.vaadin.shared.data.DataProviderConstants;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.proto.TypedGridClientRpc;
+import com.vaadin.shared.ui.proto.TypedGridServerRpc;
+import com.vaadin.shared.ui.proto.TypedGridState;
+import com.vaadin.shared.util.SharedUtil;
+
+import elemental.json.JsonObject;
+
+/**
+ * Connector implementation for TypedGrid. Uses {@link Grid} as its widget, just
+ * like {@link GridConnector}.
+ *
+ * @since
+ */
+@Connect(com.vaadin.ui.proto.TypedGrid.class)
+public class TypedGridConnector extends AbstractComponentConnector implements
+ SimpleManagedLayout, HasDataSource {
+
+ private Map<String, Column<?, JsonObject>> columnMap = new HashMap<String, Column<?, JsonObject>>();
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Grid<JsonObject> getWidget() {
+ return (Grid<JsonObject>) super.getWidget();
+ }
+
+ @Override
+ public TypedGridState getState() {
+ return (TypedGridState) super.getState();
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+
+ registerRpc(TypedGridClientRpc.class, new TypedGridClientRpc() {
+
+ @Override
+ public void setColumnOrder(String[] columnOrder) {
+ if (columnOrder.length == 0) {
+ return;
+ }
+
+ List<Column<?, JsonObject>> columns = new ArrayList<Column<?, JsonObject>>(
+ columnOrder.length);
+ for (String key : columnOrder) {
+ if (columnMap.containsKey(key)) {
+ columns.add(columnMap.get(key));
+ }
+ }
+ Column<?, JsonObject>[] c = new Column[] {};
+ getWidget().setColumnOrder(columns.toArray(c));
+ }
+ });
+
+ getWidget().addSelectionHandler(new SelectionHandler<JsonObject>() {
+
+ @Override
+ public void onSelect(SelectionEvent<JsonObject> event) {
+ String key = null;
+ if (!event.getSelected().isEmpty()) {
+ key = event.getSelected().iterator().next()
+ .getString(DataProviderConstants.KEY);
+ }
+ getRpcProxy(TypedGridServerRpc.class).setSelected(key);
+ }
+ });
+ }
+
+ public void addColumn(String key, Column<?, JsonObject> column) {
+ // TODO: Remove this when header support is implemented
+ getWidget().addColumn(column).setHeaderCaption(
+ SharedUtil.propertyIdToHumanFriendly(key));
+
+ columnMap.put(key, column);
+ }
+
+ public void removeColumn(String key) {
+ if (columnMap.containsKey(key)) {
+ getWidget().removeColumn(columnMap.remove(key));
+ }
+ }
+
+ @Override
+ public void setDataSource(DataSource<JsonObject> ds) {
+ getWidget().setDataSource(ds);
+ }
+
+ @Override
+ public void layout() {
+ getWidget().onResize();
+ }
+}
diff --git a/server/src/com/vaadin/ui/proto/Column.java b/server/src/com/vaadin/ui/proto/Column.java
new file mode 100644
index 0000000000..10a1b93ec4
--- /dev/null
+++ b/server/src/com/vaadin/ui/proto/Column.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ui.proto;
+
+import com.vaadin.server.communication.data.typed.TypedDataGenerator;
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.shared.ui.proto.TypedGridColumnState;
+import com.vaadin.ui.proto.TypedGrid.AbstractTypedGridExtension;
+
+import elemental.json.Json;
+import elemental.json.JsonObject;
+
+/**
+ * Grid Column.
+ *
+ * @param <T>
+ * grid data type
+ * @param <V>
+ * column value type
+ */
+public class Column<T, V> extends AbstractTypedGridExtension<T> implements
+ TypedDataGenerator<T> {
+
+ private ValueProvider<T, V> valueProvider;
+
+ Column(TypedGrid<T> grid, String id, Class<V> valueType,
+ ValueProvider<T, V> valueProvider) {
+ super(grid);
+ getState().id = id;
+ this.valueProvider = valueProvider;
+ // TODO: determine renderer from valueType
+ }
+
+ @Override
+ protected TypedGridColumnState getState() {
+ return (TypedGridColumnState) super.getState();
+ }
+
+ @Override
+ public void generateData(T data, JsonObject jsonObject) {
+ JsonObject dataObject;
+ if (!jsonObject.hasKey(GridState.JSONKEY_DATA)) {
+ jsonObject.put(GridState.JSONKEY_DATA, Json.createObject());
+ }
+ dataObject = jsonObject.getObject(GridState.JSONKEY_DATA);
+
+ V value = valueProvider.getValue(data);
+ dataObject.put(getState().id, value != null ? value.toString() : "");
+ }
+
+ @Override
+ public void destroyData(T data) {
+ }
+}
diff --git a/server/src/com/vaadin/ui/proto/TypedGrid.java b/server/src/com/vaadin/ui/proto/TypedGrid.java
new file mode 100644
index 0000000000..a2d86e19aa
--- /dev/null
+++ b/server/src/com/vaadin/ui/proto/TypedGrid.java
@@ -0,0 +1,275 @@
+/*
+ * 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.ui.proto;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.vaadin.data.util.BeanUtil;
+import com.vaadin.server.AbstractExtension;
+import com.vaadin.server.Extension;
+import com.vaadin.server.communication.data.typed.CollectionDataSource;
+import com.vaadin.server.communication.data.typed.DataProvider;
+import com.vaadin.server.communication.data.typed.DataSource;
+import com.vaadin.server.communication.data.typed.TypedDataGenerator;
+import com.vaadin.shared.ui.proto.TypedGridClientRpc;
+import com.vaadin.shared.ui.proto.TypedGridServerRpc;
+import com.vaadin.shared.ui.proto.TypedGridState;
+import com.vaadin.ui.AbstractComponent;
+
+/**
+ * A typed version of the Grid component. This TypedGrid is using the new typed
+ * data system.
+ * <p>
+ * Note: This component does not yet provide all original Grid features.
+ *
+ * @since
+ * @param <T>
+ * type of data objects stored in this grid, e.g. Person bean
+ */
+public class TypedGrid<T> extends AbstractComponent {
+
+ // TODO: Refactor this to use some common "Select" API and extract it from
+ // TypedGrid
+ public static class SelectEvent<T> extends EventObject {
+
+ private final T selected;
+ private final TypedGrid<T> component;
+
+ SelectEvent(TypedGrid<T> source, T selected) {
+ super(source);
+ component = source;
+ this.selected = selected;
+ }
+
+ @Override
+ public TypedGrid<T> getSource() {
+ return component;
+ }
+
+ public T getSelected() {
+ return selected;
+ }
+
+ }
+
+ // TODO: Extract from TypedGrid when extracting the SelectEvent
+ public static interface SelectionListener<T> extends Serializable {
+ void select(SelectEvent<T> select);
+ }
+
+ public abstract static class AbstractTypedGridExtension<T> extends
+ AbstractExtension {
+ public AbstractTypedGridExtension(TypedGrid<T> grid) {
+ super(grid);
+ }
+ }
+
+ private T selected;
+
+ private final Map<String, Column<T, ?>> columns = new HashMap<String, Column<T, ?>>();
+ private final Set<SelectionListener<T>> listeners = new HashSet<SelectionListener<T>>();
+ private DataProvider<T> dp;
+
+ /**
+ * Constructs a new empty Grid.
+ */
+ public TypedGrid() {
+ this(new ArrayList<T>());
+ }
+
+ /**
+ * Constructs a new Grid using the data from given collection.
+ *
+ * @param data
+ * collection of data
+ */
+ public TypedGrid(Collection<T> data) {
+ this(new CollectionDataSource<T>(data));
+ }
+
+ /**
+ * Constructs a new Grid using the given data source.
+ *
+ * @param data
+ * data source to use
+ */
+ public TypedGrid(DataSource<T> data) {
+ internalSetDataSource(data);
+ init();
+ setSizeFull();
+ }
+
+ /**
+ * Constructs a new Grid using the given data source.
+ * <p>
+ * This constructor uses the given class parameter to autodetect the columns
+ * needed to display the data.
+ *
+ * @param cls
+ * data type class
+ * @param data
+ * data source to use
+ */
+ public TypedGrid(Class<T> cls, DataSource<T> data) {
+ this(data);
+ autodetectColumns(cls);
+ }
+
+ /**
+ * Constructs a new Grid using the data from given collection.
+ * <p>
+ * This constructor uses the given class parameter to autodetect the columns
+ * needed to display the data.
+ *
+ * @param cls
+ * data type class
+ * @param data
+ * collection of data
+ */
+ public TypedGrid(Class<T> cls, Collection<T> data) {
+ this(cls, new CollectionDataSource<T>(data));
+ }
+
+ public void setDataSource(DataSource<T> data) {
+ internalSetDataSource(data);
+ }
+
+ public void setDataSource(Collection<T> data) {
+ internalSetDataSource(new CollectionDataSource<T>(data));
+ }
+
+ protected void init() {
+ registerRpc(new TypedGridServerRpc() {
+
+ @Override
+ public void setSelected(String rowKey) {
+ if (rowKey != null && !rowKey.isEmpty()) {
+ selected = dp.getKeyMapper().get(rowKey);
+ } else {
+ selected = null;
+ }
+ fireSelectionEvent(selected);
+ }
+ });
+ }
+
+ private void internalSetDataSource(DataSource<T> data) {
+ if (dp != null) {
+ dp.remove();
+ }
+
+ dp = DataProvider.create(data, this);
+ }
+
+ private void autodetectColumns(Class<T> cls) {
+ List<PropertyDescriptor> props;
+ try {
+ props = BeanUtil.getBeanPropertyDescriptor(cls);
+ for (final PropertyDescriptor p : props) {
+ if (p.getName().equals("class")) {
+ continue;
+ }
+
+ addColumn(p.getName(), (Class<Object>) p.getPropertyType(),
+ new ValueProvider<T, Object>() {
+
+ @Override
+ public Object getValue(T data) {
+ try {
+ return p.getReadMethod().invoke(data);
+ } catch (Exception e) {
+ // TODO: Improve exception handling
+ return null;
+ }
+ }
+ });
+ }
+ } catch (IntrospectionException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public <V> Column<T, V> addColumn(String name, Class<V> valueType,
+ ValueProvider<T, V> valueProvider) {
+ Column<T, V> column = new Column<T, V>(this, name, valueType,
+ valueProvider);
+ columns.put(name, column);
+ return column;
+ }
+
+ public void removeColumn(String colName) {
+ if (columns.containsKey(colName)) {
+ columns.remove(colName).remove();
+ }
+ }
+
+ public void setColumnOrder(String... columns) {
+ getRpcProxy(TypedGridClientRpc.class).setColumnOrder(columns);
+ }
+
+ @Override
+ protected TypedGridState getState() {
+ return (TypedGridState) super.getState();
+ }
+
+ @Override
+ protected void addExtension(Extension extension) {
+ super.addExtension(extension);
+
+ if (extension instanceof TypedDataGenerator) {
+ dp.addDataGenerator((TypedDataGenerator<T>) extension);
+ }
+ }
+
+ @Override
+ public void removeExtension(Extension extension) {
+ super.removeExtension(extension);
+
+ if (extension instanceof TypedDataGenerator) {
+ dp.removeDataGenerator((TypedDataGenerator<T>) extension);
+ }
+ }
+
+ public void addSelectionListener(SelectionListener<T> listener) {
+ listeners.add(listener);
+ }
+
+ public void removeSelectionListener(SelectionListener<T> listener) {
+ listeners.remove(listener);
+ }
+
+ protected void fireSelectionEvent(T selected) {
+ List<SelectionListener<T>> set = new ArrayList<SelectionListener<T>>(
+ listeners);
+ for (SelectionListener<T> l : set) {
+ l.select(new SelectEvent<T>(this, selected));
+ }
+ }
+
+ public T getSelected() {
+ return selected;
+ }
+} \ No newline at end of file
diff --git a/server/src/com/vaadin/ui/proto/ValueProvider.java b/server/src/com/vaadin/ui/proto/ValueProvider.java
new file mode 100644
index 0000000000..edc45f7392
--- /dev/null
+++ b/server/src/com/vaadin/ui/proto/ValueProvider.java
@@ -0,0 +1,22 @@
+/*
+ * 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.ui.proto;
+
+import java.io.Serializable;
+
+public interface ValueProvider<T, V> extends Serializable {
+ V getValue(T data);
+}
diff --git a/shared/src/com/vaadin/shared/ui/proto/TypedGridClientRpc.java b/shared/src/com/vaadin/shared/ui/proto/TypedGridClientRpc.java
new file mode 100644
index 0000000000..4fcec759bf
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/proto/TypedGridClientRpc.java
@@ -0,0 +1,24 @@
+/*
+ * 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.shared.ui.proto;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+public interface TypedGridClientRpc extends ClientRpc {
+
+ void setColumnOrder(String[] columnOrder);
+
+}
diff --git a/shared/src/com/vaadin/shared/ui/proto/TypedGridColumnState.java b/shared/src/com/vaadin/shared/ui/proto/TypedGridColumnState.java
new file mode 100644
index 0000000000..26b229f793
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/proto/TypedGridColumnState.java
@@ -0,0 +1,24 @@
+/*
+ * 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.shared.ui.proto;
+
+import com.vaadin.shared.communication.SharedState;
+
+public class TypedGridColumnState extends SharedState {
+
+ public String id;
+
+}
diff --git a/shared/src/com/vaadin/shared/ui/proto/TypedGridServerRpc.java b/shared/src/com/vaadin/shared/ui/proto/TypedGridServerRpc.java
new file mode 100644
index 0000000000..467422c743
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/proto/TypedGridServerRpc.java
@@ -0,0 +1,23 @@
+/*
+ * 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.shared.ui.proto;
+
+import com.vaadin.shared.communication.ServerRpc;
+
+public interface TypedGridServerRpc extends ServerRpc {
+
+ void setSelected(String rowKey);
+}
diff --git a/shared/src/com/vaadin/shared/ui/proto/TypedGridState.java b/shared/src/com/vaadin/shared/ui/proto/TypedGridState.java
new file mode 100644
index 0000000000..9fe8260462
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/proto/TypedGridState.java
@@ -0,0 +1,21 @@
+/*
+ * 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.shared.ui.proto;
+
+import com.vaadin.shared.AbstractComponentState;
+
+public class TypedGridState extends AbstractComponentState {
+}
diff --git a/uitest/src/com/vaadin/tests/proto/TypedGridUI.java b/uitest/src/com/vaadin/tests/proto/TypedGridUI.java
new file mode 100644
index 0000000000..41eaa6c71e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/proto/TypedGridUI.java
@@ -0,0 +1,45 @@
+/*
+ * 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.proto;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.fieldgroup.ComplexPerson;
+import com.vaadin.ui.proto.TypedGrid;
+
+public class TypedGridUI extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(new TypedGrid<ComplexPerson>(ComplexPerson.class,
+ createPersons(100)));
+ }
+
+ private static Collection<ComplexPerson> createPersons(int count) {
+ Random r = new Random(1337);
+ List<ComplexPerson> list = new ArrayList<ComplexPerson>();
+ for (int i = 0; i < count; ++i) {
+ list.add(ComplexPerson.create(r));
+ }
+ return list;
+ }
+
+}