summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java2
-rw-r--r--client/src/main/java/com/vaadin/client/data/CacheStrategy.java2
-rw-r--r--client/src/main/java/com/vaadin/client/data/DataSource.java22
-rw-r--r--client/src/main/java/com/vaadin/client/data/SimpleDataChangeHandler.java103
-rw-r--r--client/src/main/java/com/vaadin/client/widget/escalator/RowVisibilityChangeEvent.java2
-rw-r--r--client/src/main/java/com/vaadin/client/widget/grid/DataAvailableEvent.java2
-rw-r--r--client/src/main/java/com/vaadin/client/widgets/Escalator.java2
-rw-r--r--client/src/main/java/com/vaadin/client/widgets/Grid.java2
-rw-r--r--client/src/test/java/com/vaadin/client/ui/grid/PartitioningTest.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/RowVisibilityChangeEvent.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/DataAvailableEvent.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java2
-rw-r--r--compatibility-server/src/main/java/com/vaadin/v7/server/communication/data/RpcDataProviderExtension.java2
-rw-r--r--server/src/main/java/com/vaadin/server/data/DataCommunicator.java2
-rw-r--r--shared/src/main/java/com/vaadin/shared/Range.java (renamed from shared/src/main/java/com/vaadin/shared/ui/grid/Range.java)2
-rw-r--r--shared/src/test/java/com/vaadin/shared/ui/grid/RangeTest.java2
-rw-r--r--uitest/src/main/java/com/vaadin/tests/data/DummyData.java117
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/data/DummyComponentConnector.java43
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/client/GridDetailsClientTest.java2
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java2
-rw-r--r--uitest/src/test/java/com/vaadin/tests/data/DummyDataTest.java60
24 files changed, 364 insertions, 19 deletions
diff --git a/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java b/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java
index 95e013ed28..71568cac7a 100644
--- a/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java
+++ b/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java
@@ -28,8 +28,8 @@ import com.google.gwt.core.client.Duration;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.vaadin.client.Profiler;
+import com.vaadin.shared.Range;
import com.vaadin.shared.Registration;
-import com.vaadin.shared.ui.grid.Range;
/**
* Base implementation for data sources that fetch data from a remote system.
diff --git a/client/src/main/java/com/vaadin/client/data/CacheStrategy.java b/client/src/main/java/com/vaadin/client/data/CacheStrategy.java
index 9410223ab2..acfadcbcf7 100644
--- a/client/src/main/java/com/vaadin/client/data/CacheStrategy.java
+++ b/client/src/main/java/com/vaadin/client/data/CacheStrategy.java
@@ -16,7 +16,7 @@
package com.vaadin.client.data;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
/**
* Determines what data an {@link AbstractRemoteDataSource} should fetch and
diff --git a/client/src/main/java/com/vaadin/client/data/DataSource.java b/client/src/main/java/com/vaadin/client/data/DataSource.java
index 3457b7b9fc..fdec4b9a38 100644
--- a/client/src/main/java/com/vaadin/client/data/DataSource.java
+++ b/client/src/main/java/com/vaadin/client/data/DataSource.java
@@ -16,6 +16,9 @@
package com.vaadin.client.data;
+import java.util.function.Consumer;
+
+import com.vaadin.shared.Range;
import com.vaadin.shared.Registration;
/**
@@ -104,7 +107,7 @@ public interface DataSource<T> {
* override of an existing method, we're defining a new method for that
* instead.
*
- * @param rowHandle
+ * @param obj
* the reference object with which to compare
* @return {@code true} if this object is the same as the obj argument;
* {@code false} otherwise.
@@ -182,11 +185,28 @@ public interface DataSource<T> {
*
* @param dataChangeHandler
* the data change handler
+ *
+ * @return registration for removing the handler
*/
public Registration addDataChangeHandler(
DataChangeHandler dataChangeHandler);
/**
+ * Sets a simple data change handler for a widget without lazy loading.
+ * Refresh method should reset all the data in the widget.
+ *
+ * @param refreshMethod
+ * a method to refresh all data in the widget
+ *
+ * @return registration for removing the handler
+ */
+ public default Registration addDataChangeHandler(
+ Consumer<Range> refreshMethod) {
+ return addDataChangeHandler(
+ new SimpleDataChangeHandler(this, refreshMethod));
+ }
+
+ /**
* Gets a {@link RowHandle} of a row object in the cache.
*
* @param row
diff --git a/client/src/main/java/com/vaadin/client/data/SimpleDataChangeHandler.java b/client/src/main/java/com/vaadin/client/data/SimpleDataChangeHandler.java
new file mode 100644
index 0000000000..46fb019f3c
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/data/SimpleDataChangeHandler.java
@@ -0,0 +1,103 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.data;
+
+import java.util.function.Consumer;
+
+import com.google.gwt.core.client.Scheduler;
+import com.vaadin.shared.Range;
+
+/**
+ * Helper class for creating a {@link DataChangeHandler} for a Widget that does
+ * not support lazy loading.
+ *
+ * @author Vaadin Ltd
+ * @since
+ */
+public class SimpleDataChangeHandler implements DataChangeHandler {
+
+ /**
+ * Class to request the data source to get the full data set.
+ */
+ private static class DelayedResetScheduler {
+
+ private final DataSource<?> dataSource;
+ private boolean scheduled = false;
+
+ public DelayedResetScheduler(DataSource<?> dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ public void schedule() {
+ if (scheduled) {
+ return;
+ }
+ Scheduler.get().scheduleFinally(() -> {
+ dataSource.ensureAvailability(0, dataSource.size());
+ scheduled = false;
+ });
+ scheduled = true;
+ }
+
+ public int getExpectedSize() {
+ return dataSource.size();
+ }
+
+ public boolean isScheduled() {
+ return scheduled;
+ }
+ }
+
+ private final DelayedResetScheduler scheduler;
+ private final Consumer<Range> refreshMethod;
+
+ SimpleDataChangeHandler(DataSource<?> dataSource,
+ Consumer<Range> refreshMethod) {
+ scheduler = new DelayedResetScheduler(dataSource);
+ this.refreshMethod = refreshMethod;
+ }
+
+ @Override
+ public void dataUpdated(int firstRowIndex, int numberOfRows) {
+ scheduler.schedule();
+ }
+
+ @Override
+ public void dataRemoved(int firstRowIndex, int numberOfRows) {
+ scheduler.schedule();
+ }
+
+ @Override
+ public void dataAdded(int firstRowIndex, int numberOfRows) {
+ scheduler.schedule();
+ }
+
+ @Override
+ public void dataAvailable(int firstRowIndex, int numberOfRows) {
+ if (!scheduler.isScheduled() && firstRowIndex == 0
+ && numberOfRows == scheduler.getExpectedSize()) {
+ // All data should now be available.
+ refreshMethod.accept(Range.withLength(firstRowIndex, numberOfRows));
+ } else {
+ scheduler.schedule();
+ }
+ }
+
+ @Override
+ public void resetDataAndSize(int newSize) {
+ scheduler.schedule();
+ }
+}
diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/RowVisibilityChangeEvent.java b/client/src/main/java/com/vaadin/client/widget/escalator/RowVisibilityChangeEvent.java
index ce4be72b68..a36b591fd0 100644
--- a/client/src/main/java/com/vaadin/client/widget/escalator/RowVisibilityChangeEvent.java
+++ b/client/src/main/java/com/vaadin/client/widget/escalator/RowVisibilityChangeEvent.java
@@ -17,7 +17,7 @@
package com.vaadin.client.widget.escalator;
import com.google.gwt.event.shared.GwtEvent;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
/**
* Event fired when the range of visible rows changes e.g. because of scrolling.
diff --git a/client/src/main/java/com/vaadin/client/widget/grid/DataAvailableEvent.java b/client/src/main/java/com/vaadin/client/widget/grid/DataAvailableEvent.java
index f4ecf11677..8441a16bc5 100644
--- a/client/src/main/java/com/vaadin/client/widget/grid/DataAvailableEvent.java
+++ b/client/src/main/java/com/vaadin/client/widget/grid/DataAvailableEvent.java
@@ -16,7 +16,7 @@
package com.vaadin.client.widget.grid;
import com.google.gwt.event.shared.GwtEvent;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
/**
* Event object describing a change of row availability in DataSource of a Grid.
diff --git a/client/src/main/java/com/vaadin/client/widgets/Escalator.java b/client/src/main/java/com/vaadin/client/widgets/Escalator.java
index a5e95a26a5..35978b7cb0 100644
--- a/client/src/main/java/com/vaadin/client/widgets/Escalator.java
+++ b/client/src/main/java/com/vaadin/client/widgets/Escalator.java
@@ -89,8 +89,8 @@ import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
import com.vaadin.client.widget.grid.events.ScrollEvent;
import com.vaadin.client.widget.grid.events.ScrollHandler;
import com.vaadin.client.widgets.Escalator.JsniUtil.TouchHandlerBundle;
+import com.vaadin.shared.Range;
import com.vaadin.shared.ui.grid.HeightMode;
-import com.vaadin.shared.ui.grid.Range;
import com.vaadin.shared.ui.grid.ScrollDestination;
import com.vaadin.shared.util.SharedUtil;
diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java
index 990c85dd1c..85c6d48942 100644
--- a/client/src/main/java/com/vaadin/client/widgets/Grid.java
+++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java
@@ -174,13 +174,13 @@ import com.vaadin.client.widgets.Escalator.SubPartArguments;
import com.vaadin.client.widgets.Grid.Editor.State;
import com.vaadin.client.widgets.Grid.StaticSection.StaticCell;
import com.vaadin.client.widgets.Grid.StaticSection.StaticRow;
+import com.vaadin.shared.Range;
import com.vaadin.shared.Registration;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.grid.GridConstants;
import com.vaadin.shared.ui.grid.GridConstants.Section;
import com.vaadin.shared.ui.grid.GridStaticCellType;
import com.vaadin.shared.ui.grid.HeightMode;
-import com.vaadin.shared.ui.grid.Range;
import com.vaadin.shared.ui.grid.ScrollDestination;
import com.vaadin.shared.util.SharedUtil;
diff --git a/client/src/test/java/com/vaadin/client/ui/grid/PartitioningTest.java b/client/src/test/java/com/vaadin/client/ui/grid/PartitioningTest.java
index ac4d39006a..8be729e7c4 100644
--- a/client/src/test/java/com/vaadin/client/ui/grid/PartitioningTest.java
+++ b/client/src/test/java/com/vaadin/client/ui/grid/PartitioningTest.java
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
@SuppressWarnings("static-method")
public class PartitioningTest {
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java
index bdaf0f1f88..5103abb285 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java
@@ -29,8 +29,8 @@ import com.vaadin.client.ServerConnector;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.data.DataSource;
import com.vaadin.client.data.DataSource.RowHandle;
+import com.vaadin.shared.Range;
import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.grid.Range;
import com.vaadin.v7.client.renderers.ComplexRenderer;
import com.vaadin.v7.client.renderers.Renderer;
import com.vaadin.v7.client.widget.grid.DataAvailableEvent;
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java
index 439305d718..363d3c047d 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java
@@ -23,10 +23,10 @@ import java.util.List;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.data.AbstractRemoteDataSource;
import com.vaadin.client.extensions.AbstractExtensionConnector;
+import com.vaadin.shared.Range;
import com.vaadin.shared.data.DataProviderRpc;
import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.grid.Range;
import com.vaadin.v7.shared.ui.grid.GridState;
import elemental.json.Json;
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/RowVisibilityChangeEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/RowVisibilityChangeEvent.java
index d5c0001594..ad2b6c65a6 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/RowVisibilityChangeEvent.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/RowVisibilityChangeEvent.java
@@ -17,7 +17,7 @@
package com.vaadin.v7.client.widget.escalator;
import com.google.gwt.event.shared.GwtEvent;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
/**
* Event fired when the range of visible rows changes e.g. because of scrolling.
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/DataAvailableEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/DataAvailableEvent.java
index 37b171894d..9f51c73047 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/DataAvailableEvent.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/DataAvailableEvent.java
@@ -16,7 +16,7 @@
package com.vaadin.v7.client.widget.grid;
import com.google.gwt.event.shared.GwtEvent;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
/**
* Event object describing a change of row availability in DataSource of a Grid.
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java
index f8f4848508..0804a0ad5e 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java
@@ -65,7 +65,7 @@ import com.vaadin.client.DeferredWorker;
import com.vaadin.client.Profiler;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.ui.SubPartAware;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.v7.client.widget.escalator.Cell;
import com.vaadin.v7.client.widget.escalator.ColumnConfiguration;
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java
index 9069c95e41..e79237702b 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java
@@ -90,9 +90,9 @@ import com.vaadin.client.ui.dd.DragAndDropHandler.DragAndDropCallback;
import com.vaadin.client.ui.dd.DragHandle;
import com.vaadin.client.ui.dd.DragHandle.DragHandleCallback;
import com.vaadin.client.widgets.Overlay;
+import com.vaadin.shared.Range;
import com.vaadin.shared.Registration;
import com.vaadin.shared.data.sort.SortDirection;
-import com.vaadin.shared.ui.grid.Range;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.v7.client.renderers.ComplexRenderer;
import com.vaadin.v7.client.renderers.Renderer;
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/server/communication/data/RpcDataProviderExtension.java b/compatibility-server/src/main/java/com/vaadin/v7/server/communication/data/RpcDataProviderExtension.java
index ce960fa5fd..7fdcd4eff4 100644
--- a/compatibility-server/src/main/java/com/vaadin/v7/server/communication/data/RpcDataProviderExtension.java
+++ b/compatibility-server/src/main/java/com/vaadin/v7/server/communication/data/RpcDataProviderExtension.java
@@ -29,9 +29,9 @@ import java.util.Set;
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.KeyMapper;
+import com.vaadin.shared.Range;
import com.vaadin.shared.data.DataProviderRpc;
import com.vaadin.shared.data.DataRequestRpc;
-import com.vaadin.shared.ui.grid.Range;
import com.vaadin.v7.data.Container;
import com.vaadin.v7.data.Container.Indexed;
import com.vaadin.v7.data.Container.Indexed.ItemAddEvent;
diff --git a/server/src/main/java/com/vaadin/server/data/DataCommunicator.java b/server/src/main/java/com/vaadin/server/data/DataCommunicator.java
index 7bf9707741..8c92ad50e3 100644
--- a/server/src/main/java/com/vaadin/server/data/DataCommunicator.java
+++ b/server/src/main/java/com/vaadin/server/data/DataCommunicator.java
@@ -31,10 +31,10 @@ import java.util.stream.Stream;
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.KeyMapper;
+import com.vaadin.shared.Range;
import com.vaadin.shared.data.DataCommunicatorClientRpc;
import com.vaadin.shared.data.DataCommunicatorConstants;
import com.vaadin.shared.data.DataRequestRpc;
-import com.vaadin.shared.ui.grid.Range;
import elemental.json.Json;
import elemental.json.JsonArray;
diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/Range.java b/shared/src/main/java/com/vaadin/shared/Range.java
index 93805e4c0b..98d9ba54e2 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/grid/Range.java
+++ b/shared/src/main/java/com/vaadin/shared/Range.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.vaadin.shared.ui.grid;
+package com.vaadin.shared;
import java.io.Serializable;
diff --git a/shared/src/test/java/com/vaadin/shared/ui/grid/RangeTest.java b/shared/src/test/java/com/vaadin/shared/ui/grid/RangeTest.java
index bde581022b..921edf145e 100644
--- a/shared/src/test/java/com/vaadin/shared/ui/grid/RangeTest.java
+++ b/shared/src/test/java/com/vaadin/shared/ui/grid/RangeTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test;
+import com.vaadin.shared.Range;
+
@SuppressWarnings("static-method")
public class RangeTest {
diff --git a/uitest/src/main/java/com/vaadin/tests/data/DummyData.java b/uitest/src/main/java/com/vaadin/tests/data/DummyData.java
new file mode 100644
index 0000000000..60b3af7681
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/data/DummyData.java
@@ -0,0 +1,117 @@
+package com.vaadin.tests.data;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.data.DataCommunicator;
+import com.vaadin.server.data.ListDataSource;
+import com.vaadin.server.data.Query;
+import com.vaadin.shared.data.DataCommunicatorConstants;
+import com.vaadin.shared.data.selection.SelectionModel;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.tests.widgetset.TestingWidgetSet;
+import com.vaadin.ui.AbstractListing;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.HorizontalLayout;
+
+@Widgetset(TestingWidgetSet.NAME)
+public class DummyData extends AbstractTestUIWithLog {
+
+ /**
+ * DataSource that keeps track on how often the data is requested.
+ */
+ private class LoggingDataSource extends ListDataSource<String> {
+ private int count = 0;
+
+ private LoggingDataSource(Collection<String> collection) {
+ super(collection);
+ }
+
+ @Override
+ public Stream<String> apply(Query query) {
+ log("Backend request #" + (count++));
+ return super.apply(query);
+ }
+ }
+
+ /**
+ * Simplified server only selection model. Selection state passed in data,
+ * shown as bold text.
+ */
+ private static class DummySelectionModel implements SelectionModel<String> {
+ private String selected;
+ private DataCommunicator<String> communicator;
+
+ @Override
+ public Set<String> getSelectedItems() {
+ if (selected != null) {
+ return Collections.singleton(selected);
+ }
+ return Collections.emptySet();
+ }
+
+ @Override
+ public void select(String item) {
+ if (selected != null) {
+ communicator.refresh(selected);
+ }
+ selected = item;
+ if (selected != null) {
+ communicator.refresh(selected);
+ }
+ }
+
+ @Override
+ public void deselect(String item) {
+ if (item == selected) {
+ select(null);
+ }
+ }
+
+ private void setCommunicator(DataCommunicator<String> dataComm) {
+ communicator = dataComm;
+ }
+ }
+
+ public static class DummyComponent
+ extends AbstractListing<String, DummySelectionModel> {
+
+ private DummyComponent() {
+ setSelectionModel(new DummySelectionModel());
+ addDataGenerator((str, json) -> {
+ json.put(DataCommunicatorConstants.DATA, str);
+ if (isSelected(str)) {
+ json.put(DataCommunicatorConstants.SELECTED, true);
+ }
+ });
+ getSelectionModel().setCommunicator(getDataCommunicator());
+ }
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ DummyComponent dummy = new DummyComponent();
+ List<String> items = new ArrayList<>();
+ for (int i = 0; i < 300; ++i) {
+ items.add("Foo " + i);
+ }
+ dummy.setDataSource(new LoggingDataSource(items));
+ dummy.select("Foo 200");
+
+ HorizontalLayout controls = new HorizontalLayout();
+ addComponent(controls);
+ controls.addComponent(new Button("Select Foo 20", e -> {
+ dummy.select("Foo " + 20);
+ }));
+ controls.addComponent(new Button("Reset data source", e -> {
+ dummy.setDataSource(new LoggingDataSource(items));
+ }));
+ addComponent(dummy);
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/data/DummyComponentConnector.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/data/DummyComponentConnector.java
new file mode 100644
index 0000000000..061b52abf5
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/data/DummyComponentConnector.java
@@ -0,0 +1,43 @@
+package com.vaadin.tests.widgetset.client.data;
+
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.vaadin.client.connectors.AbstractListingConnector;
+import com.vaadin.client.data.DataSource;
+import com.vaadin.client.ui.VLabel;
+import com.vaadin.shared.data.DataCommunicatorConstants;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.tests.data.DummyData.DummyComponent;
+
+import elemental.json.JsonObject;
+
+@Connect(DummyComponent.class)
+public class DummyComponentConnector extends AbstractListingConnector {
+
+ @Override
+ public FlowPanel getWidget() {
+ return (FlowPanel) super.getWidget();
+ }
+
+ @Override
+ public void setDataSource(DataSource<JsonObject> dataSource) {
+ super.setDataSource(dataSource);
+
+ dataSource.addDataChangeHandler(range -> {
+ assert range.getStart() == 0 && range.getEnd() == dataSource
+ .size() : "Widget only supports full updates.";
+ getWidget().clear();
+ for (int i = range.getStart(); i < range.getEnd(); ++i) {
+ VLabel label = new VLabel();
+ getWidget().add(label);
+ JsonObject row = dataSource.getRow(i);
+ String text = row.getString(DataCommunicatorConstants.DATA);
+ if (row.hasKey(DataCommunicatorConstants.SELECTED)
+ && row.getBoolean(DataCommunicatorConstants.SELECTED)) {
+ text = "<b>" + text + "</b>";
+ label.addStyleName("selected");
+ }
+ label.setHTML(text);
+ }
+ });
+ }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/client/GridDetailsClientTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/client/GridDetailsClientTest.java
index ed15f13f34..1b00d14050 100644
--- a/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/client/GridDetailsClientTest.java
+++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/client/GridDetailsClientTest.java
@@ -30,7 +30,7 @@ import org.junit.Test;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
import com.vaadin.testbench.By;
import com.vaadin.testbench.ElementQuery;
import com.vaadin.testbench.TestBenchElement;
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java
index f389b4b3f3..93931d50ec 100644
--- a/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java
+++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java
@@ -33,7 +33,7 @@ import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import com.vaadin.client.WidgetUtil;
-import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.Range;
import com.vaadin.testbench.TestBenchElement;
import com.vaadin.testbench.elements.NotificationElement;
import com.vaadin.testbench.parallel.BrowserUtil;
diff --git a/uitest/src/test/java/com/vaadin/tests/data/DummyDataTest.java b/uitest/src/test/java/com/vaadin/tests/data/DummyDataTest.java
new file mode 100644
index 0000000000..48001ef27f
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/data/DummyDataTest.java
@@ -0,0 +1,60 @@
+package com.vaadin.tests.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class DummyDataTest extends SingleBrowserTest {
+
+ @Before
+ public void setUp() {
+ setDebug(true);
+ openTestURL();
+ }
+
+ @Test
+ public void testCorrectRowSelectedOnInit() {
+ List<WebElement> selected = findElements(By.className("selected"));
+ assertTrue("Only one should be selected", 1 == selected.size());
+ assertEquals("Wrong item selected", "Foo 200",
+ selected.get(0).getText());
+ }
+
+ @Test
+ public void testServerSelectionUpdatesSelected() {
+ $(ButtonElement.class).first().click();
+ List<WebElement> selected = findElements(By.className("selected"));
+ assertTrue("Only one should be selected", 1 == selected.size());
+ assertEquals("Wrong item selected", "Foo 20",
+ selected.get(0).getText());
+ }
+
+ @Test
+ public void testDataUpdateDoesNotCauseBackEndRequest() {
+ assertEquals("Unexpected backend requests", "2. Backend request #1",
+ getLogRow(0));
+ assertEquals("Unexpected backend requests", "1. Backend request #0",
+ getLogRow(1));
+ // Select a row on the server-side, triggers an update
+ $(ButtonElement.class).first().click();
+ assertEquals("No requests should have happened",
+ "2. Backend request #1", getLogRow(0));
+ }
+
+ @Test
+ public void testDataSourceChangeOnlyOneRequest() {
+ // Change to a new logging data source
+ $(ButtonElement.class).get(1).click();
+ assertEquals("DataSource change should only cause 1 request",
+ "3. Backend request #0", getLogRow(0));
+ }
+}