/* * 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.widgetset.client.grid; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.vaadin.client.data.AbstractRemoteDataSource; import com.vaadin.client.renderers.TextRenderer; import com.vaadin.client.widgets.Grid; import com.vaadin.client.widgets.Grid.SelectionMode; public class GridClientDataSourcesWidget extends PureGWTTestApplication> { private interface RestCallback { void onResponse(RestishDataSource.Backend.Result result); } /** * This is an emulated datasource that has a back-end that changes size * constantly. The back-end is unable to actively push data to Grid. * Instead, with each row request, in addition to its row payload it tells * how many rows it contains in total. * * A plausible response from this REST-like api would be: * *
     * 
     * GET /foos/4..8
     * 
     * {
     *     "resultsize": 4,
     *     "data": [
     *         [4, "foo IV"],
     *         [5, "foo V"],
     *         [6, "foo VI"]
     *         [7, "foo VII"]
     *     ],
     *     "totalrows": 100
     * }
     * 
     * 
* * In this case, the size of Grid needs to be updated to be able to show 100 * rows in total (no more, no less). * * This class *
    *
  1. gets initialized *
  2. asks for its size *
  3. updates Grid once the reply is received *
  4. as the Grid fetches more data, the total row count is dynamically * updated. *
*/ private class RestishDataSource extends AbstractRemoteDataSource { /** * Pretend like this class doesn't exist. It just simulates a backend * somewhere. *

* It's scoped inside the RDS class only because it's tied to that. * */ private class Backend { public class Result { public int size; public List rows; } private int size = 200; private int modCount = 0; public void query(int firstRowIndex, int numberOfRows, final RestCallback callback) { final Result result = new Result(); result.size = size; result.rows = fetchRows(firstRowIndex, numberOfRows); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { callback.onResponse(result); } }); } private List fetchRows(int firstRowIndex, int numberOfRows) { List rows = new ArrayList(); for (int i = 0; i < numberOfRows; i++) { String id = String.valueOf(firstRowIndex + i); rows.add(new String[] { id, "cell " + id + " #" + modCount }); } return rows; } public void pushRowChanges(int rows) { size += rows; pushRowChanges(); } public void pushRowChanges() { modCount++; // push "something happened" to datasource "over the wire": resetDataAndSize(size); } public void addRows(int rowcount) { modCount++; size += rowcount; } } final Backend backend; public RestishDataSource() { backend = new Backend(); } @Override protected void requestRows(int firstRowIndex, int numberOfRows, final RequestRowsCallback callback) { backend.query(firstRowIndex, numberOfRows, new RestCallback() { @Override public void onResponse(Backend.Result result) { callback.onResponse(result.rows, result.size); } }); } @Override public Object getRowKey(String[] row) { return row[0]; } } private final Grid grid; private RestishDataSource restishDataSource; private final ScheduledCommand setRestishCommand = new ScheduledCommand() { @Override public void execute() { for (Grid.Column column : grid.getColumns()) { grid.removeColumn(column); } restishDataSource = new RestishDataSource(); grid.setDataSource(restishDataSource); grid.addColumn(new Grid.Column("column", new TextRenderer()) { @Override public String getValue(String[] row) { return row[1]; } }); } }; public GridClientDataSourcesWidget() { super(new Grid()); grid = getTestedWidget(); grid.getElement().getStyle().setZIndex(0); grid.setHeight("400px"); grid.setSelectionMode(SelectionMode.NONE); addNorth(grid, 400); addMenuCommand("Use", setRestishCommand, "DataSources", "RESTish"); addMenuCommand("Next request +10", new ScheduledCommand() { @Override public void execute() { restishDataSource.backend.addRows(10); } }, "DataSources", "RESTish"); addMenuCommand("Next request -10", new ScheduledCommand() { @Override public void execute() { restishDataSource.backend.addRows(-10); } }, "DataSources", "RESTish"); addMenuCommand("Push data change", new ScheduledCommand() { @Override public void execute() { restishDataSource.backend.pushRowChanges(); } }, "DataSources", "RESTish"); addMenuCommand("Push data change +10", new ScheduledCommand() { @Override public void execute() { restishDataSource.backend.pushRowChanges(10); } }, "DataSources", "RESTish"); addMenuCommand("Push data change -10", new ScheduledCommand() { @Override public void execute() { restishDataSource.backend.pushRowChanges(-10); } }, "DataSources", "RESTish"); } }