summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrik Lindström <patrik@vaadin.com>2014-02-11 15:36:24 +0200
committerHenrik Paul <henrik@vaadin.com>2014-02-18 15:47:40 +0000
commitd2027d8344313b048bf3b82e2a988ab40b0bb596 (patch)
treec387db0400b72af93bcb4205e241229e44a4cb29
parent0ad5587c2f5dba0678995402dab482e81867f366 (diff)
downloadvaadin-framework-d2027d8344313b048bf3b82e2a988ab40b0bb596.tar.gz
vaadin-framework-d2027d8344313b048bf3b82e2a988ab40b0bb596.zip
Implement programmatic scrolling (#13327)
Further changes required for this, included in the same patch: - created GridClientRpc interface - created test case UI for server-side controlled Grid programmatic scrolling - refactored getScrollPos logic into Escalator and moved ScrollDestination enum to shared package Change-Id: Ibf72a4f75831807d83fb5941597a6ce3fda08e17
-rw-r--r--client/src/com/vaadin/client/ui/grid/Escalator.java143
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java90
-rw-r--r--client/src/com/vaadin/client/ui/grid/GridConnector.java19
-rw-r--r--client/src/com/vaadin/client/ui/grid/ScrollDestination.java102
-rw-r--r--client/src/com/vaadin/shared/ui/grid/ScrollDestination.java55
-rw-r--r--server/src/com/vaadin/ui/components/grid/Grid.java54
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java53
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/GridConstants.java33
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/GridScrolling.java115
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/TestGridConnector.java2
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/VTestGrid.java14
11 files changed, 509 insertions, 171 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Escalator.java b/client/src/com/vaadin/client/ui/grid/Escalator.java
index a1d895c2dd..77a8c2dbd9 100644
--- a/client/src/com/vaadin/client/ui/grid/Escalator.java
+++ b/client/src/com/vaadin/client/ui/grid/Escalator.java
@@ -52,6 +52,7 @@ import com.vaadin.client.ui.grid.PositionFunction.WebkitTranslate3DPosition;
import com.vaadin.client.ui.grid.ScrollbarBundle.HorizontalScrollbarBundle;
import com.vaadin.client.ui.grid.ScrollbarBundle.VerticalScrollbarBundle;
import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.ui.grid.ScrollDestination;
import com.vaadin.shared.util.SharedUtil;
/*-
@@ -548,6 +549,80 @@ public class Escalator extends Widget {
private static final int ROW_HEIGHT_PX = 20;
+ /**
+ * ScrollDestination case-specific handling logic.
+ */
+ private static double getScrollPos(final ScrollDestination destination,
+ final double targetStartPx, final double targetEndPx,
+ final double viewportStartPx, final double viewportEndPx,
+ final int padding) {
+
+ final double viewportLength = viewportEndPx - viewportStartPx;
+
+ switch (destination) {
+
+ /*
+ * Scroll as little as possible to show the target element. If the
+ * element fits into view, this works as START or END depending on the
+ * current scroll position. If the element does not fit into view, this
+ * works as START.
+ */
+ case ANY: {
+ final double startScrollPos = targetStartPx - padding;
+ final double endScrollPos = targetEndPx + padding - viewportLength;
+
+ if (startScrollPos < viewportStartPx) {
+ return startScrollPos;
+ } else if (targetEndPx + padding > viewportEndPx) {
+ return endScrollPos;
+ } else {
+ // NOOP, it's already visible
+ return viewportStartPx;
+ }
+ }
+
+ /*
+ * Scrolls so that the element is shown at the end of the viewport. The
+ * viewport will, however, not scroll before its first element.
+ */
+ case END: {
+ return targetEndPx + padding - viewportLength;
+ }
+
+ /*
+ * Scrolls so that the element is shown in the middle of the viewport.
+ * The viewport will, however, not scroll beyond its contents, given
+ * more elements than what the viewport is able to show at once. Under
+ * no circumstances will the viewport scroll before its first element.
+ */
+ case MIDDLE: {
+ final double targetMiddle = targetStartPx
+ + (targetEndPx - targetStartPx) / 2;
+ return targetMiddle - viewportLength / 2;
+ }
+
+ /*
+ * Scrolls so that the element is shown at the start of the viewport.
+ * The viewport will, however, not scroll beyond its contents.
+ */
+ case START: {
+ return targetStartPx - padding;
+ }
+
+ /*
+ * Throw an error if we're here. This can only mean that
+ * ScrollDestination has been carelessly amended..
+ */
+ default: {
+ throw new IllegalArgumentException(
+ "Internal: ScrollDestination has been modified, "
+ + "but Escalator.getScrollPos has not been updated "
+ + "to match new values.");
+ }
+ }
+
+ }
+
/** An inner class that handles all logic related to scrolling. */
private class Scroller extends JsniWorkaround {
private double lastScrollTop = 0;
@@ -900,7 +975,7 @@ public class Escalator extends Widget {
viewportEndPx -= Util.getNativeScrollbarSize();
}
- final double scrollLeft = destination.getScrollPos(targetStartPx,
+ final double scrollLeft = getScrollPos(destination, targetStartPx,
targetEndPx, viewportStartPx, viewportEndPx, padding);
/*
@@ -921,7 +996,7 @@ public class Escalator extends Widget {
final double viewportEndPx = viewportStartPx
+ body.calculateHeight();
- final double scrollTop = destination.getScrollPos(targetStartPx,
+ final double scrollTop = getScrollPos(destination, targetStartPx,
targetEndPx, viewportStartPx, viewportEndPx, padding);
/*
@@ -3307,33 +3382,6 @@ public class Escalator extends Widget {
/**
* Scrolls the body horizontally so that the column at the given index is
- * visible.
- *
- * @param columnIndex
- * the index of the column to scroll to
- * @param destination
- * where the column should be aligned visually after scrolling
- * @throws IndexOutOfBoundsException
- * if {@code columnIndex} is not a valid index for an existing
- * column
- * @throws IllegalArgumentException
- * if the column is frozen
- */
- public void scrollToColumn(final int columnIndex,
- final ScrollDestination destination)
- throws IndexOutOfBoundsException, IllegalArgumentException {
- verifyValidColumnIndex(columnIndex);
-
- if (columnIndex < columnConfiguration.frozenColumns) {
- throw new IllegalArgumentException("The given column index "
- + columnIndex + " is frozen.");
- }
-
- scroller.scrollToColumn(columnIndex, destination, 0);
- }
-
- /**
- * Scrolls the body horizontally so that the column at the given index is
* visible and there is at least {@code padding} pixels to the given scroll
* destination.
*
@@ -3348,14 +3396,15 @@ public class Escalator extends Widget {
* if {@code columnIndex} is not a valid index for an existing
* column
* @throws IllegalArgumentException
- * if {@code destination} is {@link ScrollDestination#MIDDLE},
- * because having a padding on a centered column is undefined
- * behavior or if the column is frozen
+ * if {@code destination} is {@link ScrollDestination#MIDDLE}
+ * and padding is nonzero, because having a padding on a
+ * centered column is undefined behavior, or if the column is
+ * frozen
*/
public void scrollToColumn(final int columnIndex,
final ScrollDestination destination, final int padding)
throws IndexOutOfBoundsException, IllegalArgumentException {
- if (destination == ScrollDestination.MIDDLE) {
+ if (destination == ScrollDestination.MIDDLE && padding != 0) {
throw new IllegalArgumentException(
"You cannot have a padding with a MIDDLE destination");
}
@@ -3379,26 +3428,6 @@ public class Escalator extends Widget {
}
/**
- * Scrolls the body vertically so that the row at the given index is
- * visible.
- *
- * @param rowIndex
- * the index of the row to scroll to
- * @param destination
- * where the row should be aligned visually after scrolling
- * @throws IndexOutOfBoundsException
- * if {@code rowIndex} is not a valid index for an existing
- * logical row
- */
- public void scrollToRow(final int rowIndex,
- final ScrollDestination destination)
- throws IndexOutOfBoundsException {
- verifyValidRowIndex(rowIndex);
-
- scroller.scrollToRow(rowIndex, destination, 0);
- }
-
- /**
* Scrolls the body vertically so that the row at the given index is visible
* and there is at least {@literal padding} pixels to the given scroll
* destination.
@@ -3413,14 +3442,14 @@ public class Escalator extends Widget {
* @throws IndexOutOfBoundsException
* if {@code rowIndex} is not a valid index for an existing row
* @throws IllegalArgumentException
- * if {@code destination} is {@link ScrollDestination#MIDDLE},
- * because having a padding on a centered row is undefined
- * behavior
+ * if {@code destination} is {@link ScrollDestination#MIDDLE}
+ * and padding is nonzero, because having a padding on a
+ * centered row is undefined behavior
*/
public void scrollToRow(final int rowIndex,
final ScrollDestination destination, final int padding)
throws IndexOutOfBoundsException, IllegalArgumentException {
- if (destination == ScrollDestination.MIDDLE) {
+ if (destination == ScrollDestination.MIDDLE && padding != 0) {
throw new IllegalArgumentException(
"You cannot have a padding with a MIDDLE destination");
}
diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java
index 015028765b..02aa194655 100644
--- a/client/src/com/vaadin/client/ui/grid/Grid.java
+++ b/client/src/com/vaadin/client/ui/grid/Grid.java
@@ -18,6 +18,7 @@ package com.vaadin.client.ui.grid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.logging.Logger;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.Element;
@@ -28,6 +29,8 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.data.DataChangeHandler;
import com.vaadin.client.data.DataSource;
import com.vaadin.client.ui.grid.renderers.TextRenderer;
+import com.vaadin.shared.ui.grid.GridConstants;
+import com.vaadin.shared.ui.grid.ScrollDestination;
import com.vaadin.shared.util.SharedUtil;
/**
@@ -1225,4 +1228,91 @@ public class Grid<T> extends Composite {
*/
return escalator.addRowVisibilityChangeHandler(handler);
}
+
+ /**
+ * Scrolls to a certain row, using {@link ScrollDestination#ANY}.
+ *
+ * @param rowIndex
+ * zero-based index of the row to scroll to.
+ * @throws IllegalArgumentException
+ * if rowIndex is below zero, or above the maximum value
+ * supported by the data source.
+ */
+ public void scrollToRow(int rowIndex) throws IllegalArgumentException {
+ scrollToRow(rowIndex, ScrollDestination.ANY,
+ GridConstants.DEFAULT_PADDING);
+ }
+
+ /**
+ * Scrolls to a certain row, using user-specified scroll destination.
+ *
+ * @param rowIndex
+ * zero-based index of the row to scroll to.
+ * @param destination
+ * desired destination placement of scrolled-to-row. See
+ * {@link ScrollDestination} for more information.
+ * @throws IllegalArgumentException
+ * if rowIndex is below zero, or above the maximum value
+ * supported by the data source.
+ */
+ public void scrollToRow(int rowIndex, ScrollDestination destination)
+ throws IllegalArgumentException {
+ scrollToRow(rowIndex, destination,
+ destination == ScrollDestination.MIDDLE ? 0
+ : GridConstants.DEFAULT_PADDING);
+ }
+
+ /**
+ * Scrolls to a certain row using only user-specified parameters.
+ *
+ * @param rowIndex
+ * zero-based index of the row to scroll to.
+ * @param destination
+ * desired destination placement of scrolled-to-row. See
+ * {@link ScrollDestination} for more information.
+ * @param paddingPx
+ * number of pixels to overscroll. Behavior depends on
+ * destination.
+ * @throws IllegalArgumentException
+ * if {@code destination} is {@link ScrollDestination#MIDDLE}
+ * and padding is nonzero, because having a padding on a
+ * centered row is undefined behavior, or if rowIndex is below
+ * zero or above the row count of the data source.
+ */
+ private void scrollToRow(int rowIndex, ScrollDestination destination,
+ int paddingPx) throws IllegalArgumentException {
+ int maxsize = escalator.getBody().getRowCount() - 1;
+
+ if (rowIndex < 0) {
+ throw new IllegalArgumentException("Row index (" + rowIndex
+ + ") is below zero!");
+ }
+
+ if (rowIndex > maxsize) {
+ throw new IllegalArgumentException("Row index (" + rowIndex
+ + ") is above maximum (" + maxsize + ")!");
+ }
+
+ escalator.scrollToRow(rowIndex, destination, paddingPx);
+ }
+
+ /**
+ * Scrolls to the beginning of the very first row.
+ */
+ public void scrollToStart() {
+ scrollToRow(0, ScrollDestination.START);
+ }
+
+ /**
+ * Scrolls to the end of the very last row.
+ */
+ public void scrollToEnd() {
+ scrollToRow(escalator.getBody().getRowCount() - 1,
+ ScrollDestination.END);
+ }
+
+ private static final Logger getLogger() {
+ return Logger.getLogger(Grid.class.getName());
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/grid/GridConnector.java b/client/src/com/vaadin/client/ui/grid/GridConnector.java
index f04326c7e6..5e0664667d 100644
--- a/client/src/com/vaadin/client/ui/grid/GridConnector.java
+++ b/client/src/com/vaadin/client/ui/grid/GridConnector.java
@@ -29,9 +29,11 @@ import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.grid.ColumnGroupRowState;
import com.vaadin.shared.ui.grid.ColumnGroupState;
+import com.vaadin.shared.ui.grid.GridClientRpc;
import com.vaadin.shared.ui.grid.GridColumnState;
import com.vaadin.shared.ui.grid.GridServerRpc;
import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.shared.ui.grid.ScrollDestination;
/**
* Connects the client side {@link Grid} widget with the server side
@@ -96,6 +98,23 @@ public class GridConnector extends AbstractComponentConnector {
event.getVisibleRowCount());
}
});
+
+ registerRpc(GridClientRpc.class, new GridClientRpc() {
+ @Override
+ public void scrollToStart() {
+ getWidget().scrollToStart();
+ }
+
+ @Override
+ public void scrollToEnd() {
+ getWidget().scrollToEnd();
+ }
+
+ @Override
+ public void scrollToRow(int row, ScrollDestination destination) {
+ getWidget().scrollToRow(row, destination);
+ }
+ });
}
@Override
diff --git a/client/src/com/vaadin/client/ui/grid/ScrollDestination.java b/client/src/com/vaadin/client/ui/grid/ScrollDestination.java
deleted file mode 100644
index e14f50ff7c..0000000000
--- a/client/src/com/vaadin/client/ui/grid/ScrollDestination.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2000-2013 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.ui.grid;
-
-/**
- * The destinations that are supported in an Escalator when scrolling rows or
- * columns into view.
- *
- * @since 7.2
- * @author Vaadin Ltd
- */
-public enum ScrollDestination {
-
- /**
- * Scroll as little as possible to show the target element. If the element
- * fits into view, this works as START or END depending on the current
- * scroll position. If the element does not fit into view, this works as
- * START.
- */
- ANY {
- @Override
- double getScrollPos(final double targetStartPx,
- final double targetEndPx, final double viewportStartPx,
- final double viewportEndPx, final int padding) {
-
- final double startScrollPos = targetStartPx - padding;
- final double viewportLength = viewportEndPx - viewportStartPx;
- final double endScrollPos = targetEndPx + padding - viewportLength;
-
- if (startScrollPos < viewportStartPx) {
- return startScrollPos;
- } else if (targetEndPx + padding > viewportEndPx) {
- return endScrollPos;
- } else {
- // NOOP, it's already visible
- return viewportStartPx;
- }
- }
- },
-
- /**
- * Scrolls so that the element is shown at the start of the viewport. The
- * viewport will, however, not scroll beyond its contents.
- */
- START {
- @Override
- double getScrollPos(final double targetStartPx,
- final double targetEndPx, final double viewportStartPx,
- final double viewportEndPx, final int padding) {
- return targetStartPx - padding;
- }
- },
-
- /**
- * Scrolls so that the element is shown in the middle of the viewport. The
- * viewport will, however, not scroll beyond its contents, given more
- * elements than what the viewport is able to show at once. Under no
- * circumstances will the viewport scroll before its first element.
- */
- MIDDLE {
- @Override
- double getScrollPos(final double targetStartPx,
- final double targetEndPx, final double viewportStartPx,
- final double viewportEndPx, final int padding) {
- final double targetMiddle = targetStartPx
- + (targetEndPx - targetStartPx) / 2;
- final double viewportLength = viewportEndPx - viewportStartPx;
- return targetMiddle - viewportLength / 2;
- }
- },
-
- /**
- * Scrolls so that the element is shown at the end of the viewport. The
- * viewport will, however, not scroll before its first element.
- */
- END {
- @Override
- double getScrollPos(final double targetStartPx,
- final double targetEndPx, final double viewportStartPx,
- final double viewportEndPx, final int padding) {
- final double viewportLength = viewportEndPx - viewportStartPx;
- return targetEndPx + padding - viewportLength;
- }
- };
-
- abstract double getScrollPos(final double targetStartPx,
- final double targetEndPx, final double viewportStartPx,
- final double viewportEndPx, final int padding);
-}
diff --git a/client/src/com/vaadin/shared/ui/grid/ScrollDestination.java b/client/src/com/vaadin/shared/ui/grid/ScrollDestination.java
new file mode 100644
index 0000000000..decc2fab5f
--- /dev/null
+++ b/client/src/com/vaadin/shared/ui/grid/ScrollDestination.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2013 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.grid;
+
+/**
+ * Enumeration, specifying the destinations that are supported when scrolling
+ * rows or columns into view.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public enum ScrollDestination {
+
+ /**
+ * Scroll as little as possible to show the target element. If the element
+ * fits into view, this works as START or END depending on the current
+ * scroll position. If the element does not fit into view, this works as
+ * START.
+ */
+ ANY,
+
+ /**
+ * Scrolls so that the element is shown at the start of the viewport. The
+ * viewport will, however, not scroll beyond its contents.
+ */
+ START,
+
+ /**
+ * Scrolls so that the element is shown in the middle of the viewport. The
+ * viewport will, however, not scroll beyond its contents, given more
+ * elements than what the viewport is able to show at once. Under no
+ * circumstances will the viewport scroll before its first element.
+ */
+ MIDDLE,
+
+ /**
+ * Scrolls so that the element is shown at the end of the viewport. The
+ * viewport will, however, not scroll before its first element.
+ */
+ END
+
+}
diff --git a/server/src/com/vaadin/ui/components/grid/Grid.java b/server/src/com/vaadin/ui/components/grid/Grid.java
index 08685874c1..4126ec6d93 100644
--- a/server/src/com/vaadin/ui/components/grid/Grid.java
+++ b/server/src/com/vaadin/ui/components/grid/Grid.java
@@ -42,10 +42,12 @@ import com.vaadin.data.Property.ValueChangeNotifier;
import com.vaadin.data.RpcDataProviderExtension;
import com.vaadin.server.KeyMapper;
import com.vaadin.shared.ui.grid.ColumnGroupRowState;
+import com.vaadin.shared.ui.grid.GridClientRpc;
import com.vaadin.shared.ui.grid.GridColumnState;
import com.vaadin.shared.ui.grid.GridServerRpc;
import com.vaadin.shared.ui.grid.GridState;
import com.vaadin.shared.ui.grid.Range;
+import com.vaadin.shared.ui.grid.ScrollDestination;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
@@ -804,4 +806,56 @@ public class Grid extends AbstractComponent {
public Object getLastFrozenPropertyId() {
return columnKeys.get(getState().lastFrozenColumnId);
}
+
+ /**
+ * Scrolls to a certain item, using {@link ScrollDestination#ANY}.
+ *
+ * @param itemId
+ * id of item to scroll to.
+ * @throws IllegalArgumentException
+ * if the provided id is not recognized by the data source.
+ */
+ public void scrollToItem(Object itemId) throws IllegalArgumentException {
+ scrollToItem(itemId, ScrollDestination.ANY);
+ }
+
+ /**
+ * Scrolls to a certain item, using user-specified scroll destination.
+ *
+ * @param itemId
+ * id of item to scroll to.
+ * @param destination
+ * value specifying desired position of scrolled-to row.
+ * @throws IllegalArgumentException
+ * if the provided id is not recognized by the data source.
+ */
+ public void scrollToItem(Object itemId, ScrollDestination destination)
+ throws IllegalArgumentException {
+
+ int row = datasource.indexOfId(itemId);
+
+ if (row == -1) {
+ throw new IllegalArgumentException(
+ "Item with specified ID does not exist in data source");
+ }
+
+ GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class);
+ clientRPC.scrollToRow(row, destination);
+ }
+
+ /**
+ * Scrolls to the beginning of the first data row.
+ */
+ public void scrollToStart() {
+ GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class);
+ clientRPC.scrollToStart();
+ }
+
+ /**
+ * Scrolls to the end of the last data row.
+ */
+ public void scrollToEnd() {
+ GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class);
+ clientRPC.scrollToEnd();
+ }
}
diff --git a/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java b/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java
new file mode 100644
index 0000000000..00cc93d371
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2013 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.grid;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+/**
+ * Server-to-client RPC interface for the Grid component.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public interface GridClientRpc extends ClientRpc {
+
+ /**
+ * Command client Grid to scroll to a specific data row.
+ *
+ * @param row
+ * zero-based row index. If the row index is below zero or above
+ * the row count of the client-side data source, a client-side
+ * exception will be triggered. Since this exception has no
+ * handling by default, an out-of-bounds value will cause a
+ * client-side crash.
+ * @param destination
+ * desired placement of scrolled-to row. See the documentation
+ * for {@link ScrollDestination} for more information.
+ */
+ public void scrollToRow(int row, ScrollDestination destination);
+
+ /**
+ * Command client Grid to scroll to the first row.
+ */
+ public void scrollToStart();
+
+ /**
+ * Command client Grid to scroll to the last row.
+ */
+ public void scrollToEnd();
+
+}
diff --git a/shared/src/com/vaadin/shared/ui/grid/GridConstants.java b/shared/src/com/vaadin/shared/ui/grid/GridConstants.java
new file mode 100644
index 0000000000..5b88fad5a8
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/grid/GridConstants.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2013 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.grid;
+
+/**
+ * Container class for common constants and default values used by the Grid
+ * component.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public final class GridConstants {
+
+ /**
+ * Default padding in pixels when scrolling programmatically, without an
+ * explicitly defined padding value.
+ */
+ public static final int DEFAULT_PADDING = 0;
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridScrolling.java b/uitest/src/com/vaadin/tests/components/grid/GridScrolling.java
new file mode 100644
index 0000000000..d514fbd0c5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/grid/GridScrolling.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2013 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;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.grid.ScrollDestination;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.components.grid.Grid;
+
+/**
+ *
+ */
+@SuppressWarnings("serial")
+public class GridScrolling extends AbstractTestUI {
+
+ private Grid grid;
+
+ private IndexedContainer ds;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void setup(VaadinRequest request) {
+ // Build data source
+ ds = new IndexedContainer();
+
+ for (int col = 0; col < 5; col++) {
+ ds.addContainerProperty("col" + col, String.class, "");
+ }
+
+ for (int row = 0; row < 65536; row++) {
+ Item item = ds.addItem(Integer.valueOf(row));
+ for (int col = 0; col < 5; col++) {
+ item.getItemProperty("col" + col).setValue(
+ "(" + row + ", " + col + ")");
+ }
+ }
+
+ grid = new Grid(ds);
+
+ HorizontalLayout hl = new HorizontalLayout();
+ hl.addComponent(grid);
+ hl.setMargin(true);
+ hl.setSpacing(true);
+
+ VerticalLayout vl = new VerticalLayout();
+ vl.setSpacing(true);
+
+ // Add scroll buttons
+ Button scrollUpButton = new Button("Top", new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ grid.scrollToStart();
+ }
+ });
+ scrollUpButton.setSizeFull();
+ vl.addComponent(scrollUpButton);
+
+ for (int i = 1; i < 7; ++i) {
+ final int row = (ds.size() / 7) * i;
+ Button scrollButton = new Button("Scroll to row " + row,
+ new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ grid.scrollToItem(Integer.valueOf(row),
+ ScrollDestination.MIDDLE);
+ }
+ });
+ scrollButton.setSizeFull();
+ vl.addComponent(scrollButton);
+ }
+
+ Button scrollDownButton = new Button("Bottom", new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ grid.scrollToEnd();
+ }
+ });
+ scrollDownButton.setSizeFull();
+ vl.addComponent(scrollDownButton);
+
+ hl.addComponent(vl);
+ addComponent(hl);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Test Grid programmatic scrolling features";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13327;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/TestGridConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/TestGridConnector.java
index f9286091c0..b8ea380301 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/TestGridConnector.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/TestGridConnector.java
@@ -16,8 +16,8 @@
package com.vaadin.tests.widgetset.client.grid;
import com.vaadin.client.ui.AbstractComponentConnector;
-import com.vaadin.client.ui.grid.ScrollDestination;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.ScrollDestination;
import com.vaadin.tests.widgetset.server.grid.TestGrid;
/**
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/VTestGrid.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/VTestGrid.java
index 5c8dd4a609..0230367b85 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/VTestGrid.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/VTestGrid.java
@@ -10,7 +10,7 @@ import com.vaadin.client.ui.grid.Escalator;
import com.vaadin.client.ui.grid.EscalatorUpdater;
import com.vaadin.client.ui.grid.Row;
import com.vaadin.client.ui.grid.RowContainer;
-import com.vaadin.client.ui.grid.ScrollDestination;
+import com.vaadin.shared.ui.grid.ScrollDestination;
public class VTestGrid extends Composite {
@@ -174,20 +174,12 @@ public class VTestGrid extends Composite {
public void scrollToRow(final int index,
final ScrollDestination destination, final int padding) {
- if (padding != 0) {
- escalator.scrollToRow(index, destination, padding);
- } else {
- escalator.scrollToRow(index, destination);
- }
+ escalator.scrollToRow(index, destination, padding);
}
public void scrollToColumn(final int index,
final ScrollDestination destination, final int padding) {
- if (padding != 0) {
- escalator.scrollToColumn(index, destination, padding);
- } else {
- escalator.scrollToColumn(index, destination);
- }
+ escalator.scrollToColumn(index, destination, padding);
}
public void removeRows(final int offset, final int amount) {