/*
* 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.tests.widgetset.client.v7.grid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Logger;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.MenuItemSeparator;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.data.DataSource;
import com.vaadin.client.data.DataSource.RowHandle;
import com.vaadin.client.ui.VLabel;
import com.vaadin.tests.widgetset.client.v7.grid.GridBasicClientFeaturesWidget.Data;
import com.vaadin.v7.client.renderers.DateRenderer;
import com.vaadin.v7.client.renderers.HtmlRenderer;
import com.vaadin.v7.client.renderers.NumberRenderer;
import com.vaadin.v7.client.renderers.Renderer;
import com.vaadin.v7.client.renderers.TextRenderer;
import com.vaadin.v7.client.widget.grid.CellReference;
import com.vaadin.v7.client.widget.grid.CellStyleGenerator;
import com.vaadin.v7.client.widget.grid.DetailsGenerator;
import com.vaadin.v7.client.widget.grid.EditorHandler;
import com.vaadin.v7.client.widget.grid.EventCellReference;
import com.vaadin.v7.client.widget.grid.RendererCellReference;
import com.vaadin.v7.client.widget.grid.RowReference;
import com.vaadin.v7.client.widget.grid.RowStyleGenerator;
import com.vaadin.v7.client.widget.grid.datasources.ListDataSource;
import com.vaadin.v7.client.widget.grid.datasources.ListSorter;
import com.vaadin.v7.client.widget.grid.events.BodyKeyDownHandler;
import com.vaadin.v7.client.widget.grid.events.BodyKeyPressHandler;
import com.vaadin.v7.client.widget.grid.events.BodyKeyUpHandler;
import com.vaadin.v7.client.widget.grid.events.ColumnReorderEvent;
import com.vaadin.v7.client.widget.grid.events.ColumnReorderHandler;
import com.vaadin.v7.client.widget.grid.events.ColumnVisibilityChangeEvent;
import com.vaadin.v7.client.widget.grid.events.ColumnVisibilityChangeHandler;
import com.vaadin.v7.client.widget.grid.events.FooterKeyDownHandler;
import com.vaadin.v7.client.widget.grid.events.FooterKeyPressHandler;
import com.vaadin.v7.client.widget.grid.events.FooterKeyUpHandler;
import com.vaadin.v7.client.widget.grid.events.GridKeyDownEvent;
import com.vaadin.v7.client.widget.grid.events.GridKeyPressEvent;
import com.vaadin.v7.client.widget.grid.events.GridKeyUpEvent;
import com.vaadin.v7.client.widget.grid.events.HeaderKeyDownHandler;
import com.vaadin.v7.client.widget.grid.events.HeaderKeyPressHandler;
import com.vaadin.v7.client.widget.grid.events.HeaderKeyUpHandler;
import com.vaadin.v7.client.widget.grid.events.ScrollEvent;
import com.vaadin.v7.client.widget.grid.events.ScrollHandler;
import com.vaadin.v7.client.widget.grid.selection.SelectionModel;
import com.vaadin.v7.client.widget.grid.selection.SelectionModel.None;
import com.vaadin.v7.client.widgets.Grid;
import com.vaadin.v7.client.widgets.Grid.Column;
import com.vaadin.v7.client.widgets.Grid.FooterRow;
import com.vaadin.v7.client.widgets.Grid.HeaderRow;
import com.vaadin.v7.client.widgets.Grid.SelectionMode;
import com.vaadin.v7.shared.ui.grid.ScrollDestination;
/**
* Grid basic client features test application.
*
* @since
* @author Vaadin Ltd
*/
public class GridBasicClientFeaturesWidget
extends PureGWTTestApplication<Grid<List<Data>>> {
public static final String ROW_STYLE_GENERATOR_NONE = "None";
public static final String ROW_STYLE_GENERATOR_ROW_INDEX = "Row numbers";
public static final String ROW_STYLE_GENERATOR_EVERY_THIRD = "Every third";
public static final String CELL_STYLE_GENERATOR_NONE = "None";
public static final String CELL_STYLE_GENERATOR_SIMPLE = "Simple";
public static final String CELL_STYLE_GENERATOR_COL_INDEX = "Column index";
public static enum Renderers {
TEXT_RENDERER, HTML_RENDERER, NUMBER_RENDERER, DATE_RENDERER;
}
private class TestEditorHandler implements EditorHandler<List<Data>> {
private Map<Grid.Column<?, ?>, TextBox> widgets = new HashMap<>();
private Label log = new Label();
{
log.addStyleName("grid-editor-log");
addSouth(log, 20);
}
@Override
public void bind(EditorRequest<List<Data>> request) {
List<Data> rowData = ds.getRow(request.getRowIndex());
boolean hasSelectionColumn = !(grid
.getSelectionModel() instanceof None);
for (int i = 0; i < rowData.size(); i++) {
int columnIndex = hasSelectionColumn ? i + 1 : i;
getWidget(columnIndex).setText(rowData.get(i).value.toString());
}
request.success();
}
@Override
public void cancel(EditorRequest<List<Data>> request) {
log.setText("Row " + request.getRowIndex() + " edit cancelled");
}
@Override
public void save(EditorRequest<List<Data>> request) {
if (secondEditorError) {
request.failure(
"Syntethic fail of editor in column 2. "
+ "This message is so long that it doesn't fit into its box",
Collections.<Column<?, List<Data>>> singleton(
grid.getColumn(2)));
return;
}
try {
log.setText("Row " + request.getRowIndex() + " edit committed");
List<Data> rowData = ds.getRow(request.getRowIndex());
int i = 0;
for (; i < COLUMNS - MANUALLY_FORMATTED_COLUMNS; i++) {
rowData.get(i).value = getWidget(i).getText();
}
rowData.get(i).value = Integer
.valueOf(getWidget(i++).getText());
rowData.get(i).value = new Date(getWidget(i++).getText());
rowData.get(i).value = getWidget(i++).getText();
rowData.get(i).value = Integer
.valueOf(getWidget(i++).getText());
rowData.get(i).value = Integer
.valueOf(getWidget(i++).getText());
// notify data source of changes
ds.asList().set(request.getRowIndex(), rowData);
request.success();
} catch (Exception e) {
Logger.getLogger(getClass().getName()).warning(e.toString());
request.failure(null, null);
}
}
@Override
public TextBox getWidget(Grid.Column<?, List<Data>> column) {
if (grid.getColumns().indexOf(column) == 0
&& !(grid.getSelectionModel() instanceof None)) {
return null;
}
TextBox w = widgets.get(column);
if (w == null) {
w = new TextBox();
w.getElement().getStyle().setMargin(0, Unit.PX);
widgets.put(column, w);
}
return w;
}
private TextBox getWidget(int i) {
return getWidget(grid.getColumn(i));
}
}
private static final int MANUALLY_FORMATTED_COLUMNS = 5;
public static final int COLUMNS = 12;
public static final int ROWS = 1000;
private final Grid<List<Data>> grid;
private List<List<Data>> data;
private final ListDataSource<List<Data>> ds;
private final ListSorter<List<Data>> sorter;
private boolean secondEditorError = false;
/**
* Our basic data object
*/
public final static class Data {
Object value;
}
/**
* @since
* @return
*/
private List<List<Data>> createData(int rowCount) {
List<List<Data>> dataList = new ArrayList<>();
Random rand = new Random();
rand.setSeed(13334);
long timestamp = 0;
for (int row = 0; row < rowCount; row++) {
List<Data> datarow = createDataRow(COLUMNS);
dataList.add(datarow);
Data d;
int col = 0;
for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; ++col) {
d = datarow.get(col);
d.value = "(" + row + ", " + col + ")";
}
d = datarow.get(col++);
d.value = Integer.valueOf(row);
d = datarow.get(col++);
d.value = new Date(timestamp);
timestamp += 91250000; // a bit over a day, just to get
// variation
d = datarow.get(col++);
d.value = "<b>" + row + "</b>";
d = datarow.get(col++);
d.value = Integer.valueOf(rand.nextInt());
d = datarow.get(col++);
d.value = Integer.valueOf(rand.nextInt(5));
}
return dataList;
}
/**
* Convenience method for creating a list of Data objects to be used as a
* Row in the data source
*
* @param cols
* number of columns (items) to include in the row
* @return
*/
private List<Data> createDataRow(int cols) {
List<Data> list = new ArrayList<>(cols);
for (int i = 0; i < cols; ++i) {
list.add(new Data());
}
return list;
}
@SuppressWarnings("unchecked")
public GridBasicClientFeaturesWidget() {
super(new Grid<List<Data>>());
// Initialize data source
data = createData(ROWS);
ds = new ListDataSource<>(data);
grid = getTestedWidget();
grid.getElement().setId("testComponent");
grid.setDataSource(ds);
grid.addSelectAllHandler(ds.getSelectAllHandler());
grid.setSelectionMode(SelectionMode.NONE);
grid.setEditorHandler(new TestEditorHandler());
sorter = new ListSorter<>(grid);
// Create a bunch of grid columns
// Data source layout:
// text (String) * (COLUMNS - MANUALLY_FORMATTED_COLUMNS + 1) |
// rownumber (Integer) | some date (Date) | row number as HTML (String)
// | random value (Integer)
int col = 0;
// Text times COLUMNS - MANUALLY_FORMATTED_COLUMNS
for (col = 0; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; ++col) {
final int c = col;
Grid.Column<String, List<Data>> column = new Grid.Column<String, List<Data>>(
createRenderer(Renderers.TEXT_RENDERER)) {
@Override
public String getValue(List<Data> row) {
return (String) row.get(c).value;
}
};
column.setWidth(50 + c * 25);
column.setHeaderCaption("Header (0," + c + ")");
grid.addColumn(column);
}
// Integer row number
{
final int c = col++;
Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>(
createRenderer(Renderers.NUMBER_RENDERER)) {
@Override
public Integer getValue(List<Data> row) {
return (Integer) row.get(c).value;
}
};
grid.addColumn(column);
column.setHeaderCaption("Header (0," + c + ")");
}
// Some date
{
final int c = col++;
Grid.Column<Date, List<Data>> column = new Grid.Column<Date, List<Data>>(
createRenderer(Renderers.DATE_RENDERER)) {
@Override
public Date getValue(List<Data> row) {
return (Date) row.get(c).value;
}
};
grid.addColumn(column);
column.setHeaderCaption("Header (0," + c + ")");
}
// Row number as a HTML string
{
final int c = col++;
Grid.Column<String, List<Data>> column = new Grid.Column<String, List<Data>>(
createRenderer(Renderers.HTML_RENDERER)) {
@Override
public String getValue(List<Data> row) {
return (String) row.get(c).value;
}
};
grid.addColumn(column);
column.setHeaderCaption("Header (0," + c + ")");
}
// Random integer value
{
final int c = col++;
Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>(
createRenderer(Renderers.NUMBER_RENDERER)) {
@Override
public Integer getValue(List<Data> row) {
return (Integer) row.get(c).value;
}
};
grid.addColumn(column);
column.setHeaderCaption("Header (0," + c + ")");
}
// Random integer value between 0 and 5
{
final int c = col++;
Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>(
createRenderer(Renderers.NUMBER_RENDERER)) {
@Override
public Integer getValue(List<Data> row) {
return (Integer) row.get(c).value;
}
};
grid.addColumn(column);
column.setHeaderCaption("Header (0," + c + ")");
}
grid.getColumn(3).setEditable(false);
HeaderRow row = grid.getDefaultHeaderRow();
for (int i = 0; i < col; ++i) {
String caption = "Header (0," + i + ")";
Grid.Column<?, ?> column = grid.getColumn(i);
// Lets use some different cell types
if (i % 3 == 0) {
// No-op
} else if (i % 2 == 0) {
row.getCell(column).setHtml("<b>" + caption + "</b>");
} else {
row.getCell(column).setWidget(new HTML(caption));
}
}
++headerCounter;
//
// Populate the menu
//
createStateMenu();
createColumnsMenu();
createHeaderMenu();
createFooterMenu();
createEditorMenu();
createInternalsMenu();
createDataSourceMenu();
createDetailsMenu();
createSidebarMenu();
grid.getElement().getStyle().setZIndex(0);
//
// Composite wrapping for grid.
//
boolean isComposite = Window.Location.getParameter("composite") != null;
if (isComposite) {
addNorth(new Composite() {
{
initWidget(grid);
}
}, 400);
} else {
addNorth(grid, 400);
}
createKeyHandlers();
}
private void createInternalsMenu() {
String[] listenersPath = { "Component", "Internals", "Listeners" };
final Label label = new Label();
addSouth(label, 20);
addMenuCommand("Add scroll listener", new ScheduledCommand() {
private HandlerRegistration scrollHandler = null;
@Override
public void execute() {
if (scrollHandler != null) {
return;
}
scrollHandler = grid.addScrollHandler(new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
@SuppressWarnings("hiding")
final Grid<?> grid = (Grid<?>) event.getSource();
label.setText("scrollTop: " + grid.getScrollTop()
+ ", scrollLeft: " + grid.getScrollLeft());
}
});
}
}, listenersPath);
addMenuCommand("Add ColumnReorder listener", new ScheduledCommand() {
private HandlerRegistration columnReorderHandler = null;
@Override
public void execute() {
if (columnReorderHandler != null) {
return;
}
final Label columnOrderLabel = new Label();
columnOrderLabel.getElement().setId("columnreorder");
addLineEnd(columnOrderLabel, 300);
columnReorderHandler = grid.addColumnReorderHandler(
new ColumnReorderHandler<List<Data>>() {
private int eventIndex = 0;
@Override
public void onColumnReorder(
ColumnReorderEvent<List<Data>> event) {
columnOrderLabel.getElement().setAttribute(
"columns", "" + (++eventIndex));
}
});
}
}, listenersPath);
addMenuCommand("Add Column Visibility Change listener",
new ScheduledCommand() {
private HandlerRegistration columnVisibilityHandler = null;
@Override
public void execute() {
if (columnVisibilityHandler != null) {
return;
}
final Label columnOrderLabel = new Label();
columnOrderLabel.getElement().setId("columnvisibility");
addLineEnd(columnOrderLabel, 250);
ColumnVisibilityChangeHandler handler = new ColumnVisibilityChangeHandler<List<Data>>() {
private int eventIndex = 0;
@Override
public void onVisibilityChange(
ColumnVisibilityChangeEvent<List<Data>> event) {
columnOrderLabel.getElement().setAttribute(
"counter", "" + (++eventIndex));
columnOrderLabel.getElement().setAttribute(
"useroriginated", (Boolean.toString(
event.isUserOriginated())));
columnOrderLabel.getElement().setAttribute(
"ishidden",
(Boolean.toString(event.isHidden())));
columnOrderLabel.getElement().setAttribute(
"columnindex", "" + grid.getColumns()
.indexOf(event.getColumn()));
}
};
columnVisibilityHandler = grid
.addColumnVisibilityChangeHandler(handler);
}
}, listenersPath);
addMenuCommand("Add context menu listener", new ScheduledCommand() {
HandlerRegistration handler = null;
ContextMenuHandler contextMenuHandler = new ContextMenuHandler() {
@Override
public void onContextMenu(ContextMenuEvent event) {
event.preventDefault();
final String location;
EventCellReference<?> cellRef = grid.getEventCell();
if (cellRef.isHeader()) {
location = "header";
} else if (cellRef.isBody()) {
location = "body";
} else if (cellRef.isFooter()) {
location = "footer";
} else {
location = "somewhere";
}
getLogger().info("Prevented opening a context menu in grid "
+ location);
}
};
@Override
public void execute() {
if (handler != null) {
grid.unsinkEvents(Event.ONCONTEXTMENU);
handler.removeHandler();
} else {
grid.sinkEvents(Event.ONCONTEXTMENU);
handler = grid.addDomHandler(contextMenuHandler,
ContextMenuEvent.getType());
}
}
}, listenersPath);
}
private void createStateMenu() {
String[] selectionModePath = { "Component", "State", "Selection mode" };
String[] primaryStyleNamePath = { "Component", "State",
"Primary Stylename" };
String[] rowStyleGeneratorNamePath = { "Component", "State",
"Row style generator" };
String[] cellStyleGeneratorNamePath = { "Component", "State",
"Cell style generator" };
addMenuCommand("multi", new ScheduledCommand() {
@Override
public void execute() {
grid.setSelectionMode(SelectionMode.MULTI);
}
}, selectionModePath);
addMenuCommand("single", new ScheduledCommand() {
@Override
public void execute() {
grid.setSelectionMode(SelectionMode.SINGLE);
}
}, selectionModePath);
addMenuCommand("single (no deselect)", new ScheduledCommand() {
@Override
public void execute() {
grid.setSelectionMode(SelectionMode.SINGLE);
((SelectionModel.Single<?>) grid.getSelectionModel())
.setDeselectAllowed(false);
}
}, selectionModePath);
addMenuCommand("none", new ScheduledCommand() {
@Override
public void execute() {
grid.setSelectionMode(SelectionMode.NONE);
}
}, selectionModePath);
addMenuCommand("v-grid", new ScheduledCommand() {
@Override
public void execute() {
grid.setStylePrimaryName("v-grid");
}
}, primaryStyleNamePath);
addMenuCommand("v-escalator", new ScheduledCommand() {
@Override
public void execute() {
grid.setStylePrimaryName("v-escalator");
}
}, primaryStyleNamePath);
addMenuCommand("v-custom-style", new ScheduledCommand() {
@Override
public void execute() {
grid.setStylePrimaryName("v-custom-style");
}
}, primaryStyleNamePath);
addMenuCommand("Edit and refresh Row 0", new ScheduledCommand() {
@Override
public void execute() {
DataSource<List<Data>> ds = grid.getDataSource();
RowHandle<List<Data>> rowHandle = ds.getHandle(ds.getRow(0));
rowHandle.getRow().get(0).value = "Foo";
rowHandle.updateRow();
}
}, "Component", "State");
addMenuCommand("Delayed edit of Row 0", new ScheduledCommand() {
@Override
public void execute() {
DataSource<List<Data>> ds = grid.getDataSource();
final RowHandle<List<Data>> rowHandle = ds
.getHandle(ds.getRow(0));
new Timer() {
@Override
public void run() {
rowHandle.getRow().get(0).value = "Bar";
rowHandle.updateRow();
}
}.schedule(5000);
}
}, "Component", "State");
addMenuCommand(ROW_STYLE_GENERATOR_NONE, new ScheduledCommand() {
@Override
public void execute() {
grid.setRowStyleGenerator(null);
}
}, rowStyleGeneratorNamePath);
addMenuCommand(ROW_STYLE_GENERATOR_EVERY_THIRD, new ScheduledCommand() {
@Override
public void execute() {
grid.setRowStyleGenerator(new RowStyleGenerator<List<Data>>() {
@Override
public String getStyle(
RowReference<List<Data>> rowReference) {
if (rowReference.getRowIndex() % 3 == 0) {
return "third";
} else {
// First manual col is integer
Integer value = (Integer) rowReference.getRow().get(
COLUMNS - MANUALLY_FORMATTED_COLUMNS).value;
return value.toString();
}
}
});
}
}, rowStyleGeneratorNamePath);
addMenuCommand(ROW_STYLE_GENERATOR_ROW_INDEX, new ScheduledCommand() {
@Override
public void execute() {
grid.setRowStyleGenerator(new RowStyleGenerator<List<Data>>() {
@Override
public String getStyle(
RowReference<List<Data>> rowReference) {
return Integer.toString(rowReference.getRowIndex());
}
});
}
}, rowStyleGeneratorNamePath);
addMenuCommand(CELL_STYLE_GENERATOR_NONE, new ScheduledCommand() {
@Override
public void execute() {
grid.setCellStyleGenerator(null);
}
}, cellStyleGeneratorNamePath);
addMenuCommand(CELL_STYLE_GENERATOR_SIMPLE, new ScheduledCommand() {
@Override
public void execute() {
grid.setCellStyleGenerator(
new CellStyleGenerator<List<Data>>() {
@Override
public String getStyle(
CellReference<List<Data>> cellReference) {
Grid.Column<?, List<Data>> column = cellReference
.getColumn();
if (column == grid.getColumn(2)) {
return "two";
} else if (column == grid.getColumn(
COLUMNS - MANUALLY_FORMATTED_COLUMNS)) {
// First manual col is integer
Integer value = (Integer) column
.getValue(cellReference.getRow());
return value.toString();
} else {
return null;
}
}
});
}
}, cellStyleGeneratorNamePath);
addMenuCommand(CELL_STYLE_GENERATOR_COL_INDEX, new ScheduledCommand() {
@Override
public void execute() {
grid.setCellStyleGenerator(
new CellStyleGenerator<List<Data>>() {
@Override
public String getStyle(
CellReference<List<Data>> cellReference) {
return cellReference.getRowIndex() + "_"
+ grid.getColumns().indexOf(
cellReference.getColumn());
}
});
}
}, cellStyleGeneratorNamePath);
for (int i = -1; i <= COLUMNS; i++) {
final int index = i;
// Including dummy "columns" prefix because TB fails to select item
// if it's too narrow
addMenuCommand(Integer.toString(index) + " columns",
new ScheduledCommand() {
@Override
public void execute() {
grid.setFrozenColumnCount(index);
}
}, "Component", "State", "Frozen column count");
}
addMenuCommand("Enabled", new ScheduledCommand() {
@Override
public void execute() {
grid.setEnabled(!grid.isEnabled());
}
}, "Component", "State");
addMenuCommand("Reverse grid columns", new ScheduledCommand() {
@Override
public void execute() {
List<Column> columns = new ArrayList<>(grid.getColumns());
Collections.reverse(columns);
grid.setColumnOrder(
columns.toArray(new Column[columns.size()]));
}
}, "Component", "State");
addMenuCommand("Column Reordering", new ScheduledCommand() {
@Override
public void execute() {
grid.setColumnReorderingAllowed(
!grid.isColumnReorderingAllowed());
}
}, "Component", "State");
addMenuCommand("250px", new ScheduledCommand() {
@Override
public void execute() {
grid.setWidth("250px");
}
}, "Component", "State", "Width");
addMenuCommand("500px", new ScheduledCommand() {
@Override
public void execute() {
grid.setWidth("500px");
}
}, "Component", "State", "Width");
addMenuCommand("750px", new ScheduledCommand() {
@Override
public void execute() {
grid.setWidth("750px");
}
}, "Component", "State", "Width");
addMenuCommand("1000px", new ScheduledCommand() {
@Override
public void execute() {
grid.setWidth("1000px");
}
}, "Component", "State", "Width");
createScrollToRowMenu();
}
private void createScrollToRowMenu() {
String[] menupath = new String[] { "Component", "State", "Scroll to...",
null };
for (int i = 0; i < ROWS; i += 100) {
menupath[3] = "Row " + i + "...";
for (final ScrollDestination scrollDestination : ScrollDestination
.values()) {
final int row = i;
addMenuCommand("Destination " + scrollDestination,
new ScheduledCommand() {
@Override
public void execute() {
grid.scrollToRow(row, scrollDestination);
}
}, menupath);
}
}
int i = ROWS - 1;
menupath[3] = "Row " + i + "...";
for (final ScrollDestination scrollDestination : ScrollDestination
.values()) {
final int row = i;
addMenuCommand("Destination " + scrollDestination,
new ScheduledCommand() {
@Override
public void execute() {
grid.scrollToRow(row, scrollDestination);
}
}, menupath);
}
}
private void createColumnsMenu() {
for (int i = 0; i < COLUMNS; i++) {
final int index = i;
final Grid.Column<?, List<Data>> column = grid.getColumn(index);
addMenuCommand("Sortable", new ScheduledCommand() {
@Override
public void execute() {
column.setSortable(!column.isSortable());
}
}, "Component", "Columns", "Column " + i);
addMenuCommand("Hidden", new ScheduledCommand() {
@Override
public void execute() {
column.setHidden(!column.isHidden());
}
}, "Component", "Columns", "Column " + i);
addMenuCommand("Hidable", new ScheduledCommand() {
@Override
public void execute() {
column.setHidable(!column.isHidable());
}
}, "Component", "Columns", "Column " + i);
addMenuCommand("auto", new ScheduledCommand() {
@Override
public void execute() {
column.setWidth(-1);
}
}, "Component", "Columns", "Column " + i, "Width");
addMenuCommand("50px", new ScheduledCommand() {
@Override
public void execute() {
column.setWidth(50);
}
}, "Component", "Columns", "Column " + i, "Width");
addMenuCommand("200px", new ScheduledCommand() {
@Override
public void execute() {
column.setWidth(200);
}
}, "Component", "Columns", "Column " + i, "Width");
// Header types
addMenuCommand("Text Header", new ScheduledCommand() {
@Override
public void execute() {
column.setHeaderCaption("Text Header");
}
}, "Component", "Columns", "Column " + i, "Header Type");
addMenuCommand("HTML Header", new ScheduledCommand() {
@Override
public void execute() {
grid.getHeaderRow(0).getCell(column)
.setHtml("<b>HTML Header</b>");
}
}, "Component", "Columns", "Column " + i, "Header Type");
addMenuCommand("Widget Header", new ScheduledCommand() {
@Override
public void execute() {
final Button button = new Button("Button Header");
button.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
button.setText("Clicked");
}
});
grid.getHeaderRow(0).getCell(column).setWidget(button);
}
}, "Component", "Columns", "Column " + i, "Header Type");
// Footer types
addMenuCommand("Text Footer", new ScheduledCommand() {
@Override
public void execute() {
grid.getFooterRow(0).getCell(column).setText("Text Footer");
}
}, "Component", "Columns", "Column " + i, "Footer Type");
addMenuCommand("HTML Footer", new ScheduledCommand() {
@Override
public void execute() {
grid.getFooterRow(0).getCell(column)
.setHtml("<b>HTML Footer</b>");
}
}, "Component", "Columns", "Column " + i, "Footer Type");
addMenuCommand("Widget Footer", new ScheduledCommand() {
@Override
public void execute() {
final Button button = new Button("Button Footer");
button.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
button.setText("Clicked");
}
});
grid.getFooterRow(0).getCell(column).setWidget(button);
}
}, "Component", "Columns", "Column " + i, "Footer Type");
// Renderer throwing exceptions
addMenuCommand("Broken renderer", new ScheduledCommand() {
@Override
public void execute() {
final Renderer<Object> originalRenderer = (Renderer<Object>) column
.getRenderer();
column.setRenderer(new Renderer<Object>() {
@Override
public void render(RendererCellReference cell,
Object data) {
if (cell.getRowIndex() == cell.getColumnIndex()) {
throw new RuntimeException("I'm broken");
}
originalRenderer.render(cell, data);
}
});
}
}, "Component", "Columns", "Column " + i);
addMenuCommand("Move column left", new ScheduledCommand() {
@SuppressWarnings("unchecked")
@Override
public void execute() {
List<Column<?, List<Data>>> cols = grid.getColumns();
ArrayList<Column> reordered = new ArrayList<>(cols);
final int index = cols.indexOf(column);
if (index == 0) {
Column<?, List<Data>> col = reordered.remove(0);
reordered.add(col);
} else {
Column<?, List<Data>> col = reordered.remove(index);
reordered.add(index - 1, col);
}
grid.setColumnOrder(
reordered.toArray(new Column[reordered.size()]));
}
}, "Component", "Columns", "Column " + i);
}
}
private int headerCounter = 0;
private int footerCounter = 0;
private void setHeaderTexts(HeaderRow row) {
for (int i = 0; i < COLUMNS; ++i) {
String caption = "Header (" + headerCounter + "," + i + ")";
// Lets use some different cell types
if (i % 3 == 0) {
row.getCell(grid.getColumn(i)).setText(caption);
} else if (i % 2 == 0) {
row.getCell(grid.getColumn(i))
.setHtml("<b>" + caption + "</b>");
} else {
row.getCell(grid.getColumn(i)).setWidget(new HTML(caption));
}
}
headerCounter++;
}
private void setFooterTexts(FooterRow row) {
for (int i = 0; i < COLUMNS; ++i) {
String caption = "Footer (" + footerCounter + "," + i + ")";
// Lets use some different cell types
if (i % 3 == 0) {
row.getCell(grid.getColumn(i)).setText(caption);
} else if (i % 2 == 0) {
row.getCell(grid.getColumn(i))
.setHtml("<b>" + caption + "</b>");
} else {
row.getCell(grid.getColumn(i)).setWidget(new HTML(caption));
}
}
footerCounter++;
}
private void createHeaderMenu() {
final String[] menuPath = { "Component", "Header" };
addMenuCommand("Visible", new ScheduledCommand() {
@Override
public void execute() {
grid.setHeaderVisible(!grid.isHeaderVisible());
}
}, menuPath);
addMenuCommand("Top", new ScheduledCommand() {
@Override
public void execute() {
grid.setDefaultHeaderRow(grid.getHeaderRow(0));
}
}, "Component", "Header", "Default row");
addMenuCommand("Bottom", new ScheduledCommand() {
@Override
public void execute() {
grid.setDefaultHeaderRow(
grid.getHeaderRow(grid.getHeaderRowCount() - 1));
}
}, "Component", "Header", "Default row");
addMenuCommand("Unset", new ScheduledCommand() {
@Override
public void execute() {
grid.setDefaultHeaderRow(null);
}
}, "Component", "Header", "Default row");
addMenuCommand("Prepend row", new ScheduledCommand() {
@Override
public void execute() {
configureHeaderRow(grid.prependHeaderRow());
}
}, menuPath);
addMenuCommand("Append row", new ScheduledCommand() {
@Override
public void execute() {
configureHeaderRow(grid.appendHeaderRow());
}
}, menuPath);
addMenuCommand("Remove top row", new ScheduledCommand() {
@Override
public void execute() {
grid.removeHeaderRow(0);
}
}, menuPath);
addMenuCommand("Remove bottom row", new ScheduledCommand() {
@Override
public void execute() {
grid.removeHeaderRow(grid.getHeaderRowCount() - 1);
}
}, menuPath);
}
private void configureHeaderRow(final HeaderRow row) {
setHeaderTexts(row);
String rowTitle = "Row " + grid.getHeaderRowCount();
final String[] menuPath = { "Component", "Header", rowTitle };
addMenuCommand("Join column cells 0, 1", new ScheduledCommand() {
@Override
public void execute() {
row.join(row.getCell(grid.getColumn(0)),
row.getCell(grid.getColumn(1)))
.setText("Join column cells 0, 1");
}
}, menuPath);
addMenuCommand("Join columns 1, 2", new ScheduledCommand() {
@Override
public void execute() {
row.join(grid.getColumn(1), grid.getColumn(2))
.setText("Join columns 1, 2");
;
}
}, menuPath);
addMenuCommand("Join columns 3, 4, 5", new ScheduledCommand() {
@Override
public void execute() {
row.join(grid.getColumn(3), grid.getColumn(4),
grid.getColumn(5)).setText("Join columns 3, 4, 5");
}
}, menuPath);
addMenuCommand("Join all columns", new ScheduledCommand() {
@Override
public void execute() {
row.join(grid.getColumns()
.toArray(new Grid.Column[grid.getColumnCount()]))
.setText("Join all columns");
;
}
}, menuPath);
}
private void createFooterMenu() {
final String[] menuPath = { "Component", "Footer" };
addMenuCommand("Visible", new ScheduledCommand() {
@Override
public void execute() {
grid.setFooterVisible(!grid.isFooterVisible());
}
}, menuPath);
addMenuCommand("Prepend row", new ScheduledCommand() {
@Override
public void execute() {
configureFooterRow(grid.prependFooterRow());
}
}, menuPath);
addMenuCommand("Append row", new ScheduledCommand() {
@Override
public void execute() {
configureFooterRow(grid.appendFooterRow());
}
}, menuPath);
addMenuCommand("Remove top row", new ScheduledCommand() {
@Override
public void execute() {
grid.removeFooterRow(0);
}
}, menuPath);
addMenuCommand("Remove bottom row", new ScheduledCommand() {
@Override
public void execute() {
assert grid.getFooterRowCount() > 0;
grid.removeFooterRow(grid.getFooterRowCount() - 1);
}
}, menuPath);
}
private void createEditorMenu() {
addMenuCommand("Enabled", new ScheduledCommand() {
@Override
public void execute() {
grid.setEditorEnabled(!grid.isEditorEnabled());
}
}, "Component", "Editor");
addMenuCommand("Edit row 5", new ScheduledCommand() {
@Override
public void execute() {
grid.editRow(5);
}
}, "Component", "Editor");
addMenuCommand("Edit row 100", new ScheduledCommand() {
@Override
public void execute() {
grid.editRow(100);
}
}, "Component", "Editor");
addMenuCommand("Save", new ScheduledCommand() {
@Override
public void execute() {
grid.saveEditor();
}
}, "Component", "Editor");
addMenuCommand("Cancel edit", new ScheduledCommand() {
@Override
public void execute() {
grid.cancelEditor();
}
}, "Component", "Editor");
addMenuCommand("Change Save Caption", new ScheduledCommand() {
@Override
public void execute() {
grid.setEditorSaveCaption("ǝʌɐS");
}
}, "Component", "Editor");
addMenuCommand("Change Cancel Caption", new ScheduledCommand() {
@Override
public void execute() {
grid.setEditorCancelCaption("ʃǝɔuɐↃ");
}
}, "Component", "Editor");
addMenuCommand("Toggle second editor error", new ScheduledCommand() {
@Override
public void execute() {
secondEditorError = !secondEditorError;
}
}, "Component", "Editor");
}
private void configureFooterRow(final FooterRow row) {
setFooterTexts(row);
String rowTitle = "Row " + grid.getFooterRowCount();
final String[] menuPath = { "Component", "Footer", rowTitle };
addMenuCommand("Join column cells 0, 1", new ScheduledCommand() {
@Override
public void execute() {
row.join(row.getCell(grid.getColumn(0)),
row.getCell(grid.getColumn(1)))
.setText("Join column cells 0, 1");
}
}, menuPath);
addMenuCommand("Join columns 1, 2", new ScheduledCommand() {
@Override
public void execute() {
row.join(grid.getColumn(1), grid.getColumn(2))
.setText("Join columns 1, 2");
;
}
}, menuPath);
addMenuCommand("Join all columns", new ScheduledCommand() {
@Override
public void execute() {
row.join(grid.getColumns()
.toArray(new Grid.Column[grid.getColumnCount()]))
.setText("Join all columns");
;
}
}, menuPath);
}
private void createDataSourceMenu() {
final String[] menuPath = { "Component", "DataSource" };
addMenuCommand("Reset with 100 rows of Data", new ScheduledCommand() {
@Override
public void execute() {
ds.asList().clear();
data = createData(100);
ds.asList().addAll(data);
}
}, menuPath);
addMenuCommand("Reset with " + ROWS + " rows of Data",
new ScheduledCommand() {
@Override
public void execute() {
ds.asList().clear();
data = createData(ROWS);
ds.asList().addAll(data);
}
}, menuPath);
}
/**
* Creates a renderer for a {@link Renderers}
*/
@SuppressWarnings("rawtypes")
private final Renderer createRenderer(Renderers renderer) {
switch (renderer) {
case TEXT_RENDERER:
return new TextRenderer();
case HTML_RENDERER:
return new HtmlRenderer() {
@Override
public void render(RendererCellReference cell,
String htmlString) {
super.render(cell, "<b>" + htmlString + "</b>");
}
};
case NUMBER_RENDERER:
return new NumberRenderer();
case DATE_RENDERER:
return new DateRenderer();
default:
return new TextRenderer();
}
}
/**
* Creates a collection of handlers for all the grid key events
*/
private void createKeyHandlers() {
final List<VLabel> labels = new ArrayList<>();
for (int i = 0; i < 9; ++i) {
VLabel tmp = new VLabel();
addNorth(tmp, 20);
labels.add(tmp);
}
// Key Down Events
grid.addBodyKeyDownHandler(new BodyKeyDownHandler() {
private final VLabel label = labels.get(0);
@Override
public void onKeyDown(GridKeyDownEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
grid.addHeaderKeyDownHandler(new HeaderKeyDownHandler() {
private final VLabel label = labels.get(1);
@Override
public void onKeyDown(GridKeyDownEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
grid.addFooterKeyDownHandler(new FooterKeyDownHandler() {
private final VLabel label = labels.get(2);
@Override
public void onKeyDown(GridKeyDownEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
// Key Up Events
grid.addBodyKeyUpHandler(new BodyKeyUpHandler() {
private final VLabel label = labels.get(3);
@Override
public void onKeyUp(GridKeyUpEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
grid.addHeaderKeyUpHandler(new HeaderKeyUpHandler() {
private final VLabel label = labels.get(4);
@Override
public void onKeyUp(GridKeyUpEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
grid.addFooterKeyUpHandler(new FooterKeyUpHandler() {
private final VLabel label = labels.get(5);
@Override
public void onKeyUp(GridKeyUpEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
// Key Press Events
grid.addBodyKeyPressHandler(new BodyKeyPressHandler() {
private final VLabel label = labels.get(6);
@Override
public void onKeyPress(GridKeyPressEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
grid.addHeaderKeyPressHandler(new HeaderKeyPressHandler() {
private final VLabel label = labels.get(7);
@Override
public void onKeyPress(GridKeyPressEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
grid.addFooterKeyPressHandler(new FooterKeyPressHandler() {
private final VLabel label = labels.get(8);
@Override
public void onKeyPress(GridKeyPressEvent event) {
CellReference<?> focused = event.getFocusedCell();
updateLabel(label, event.toDebugString(), focused.getRowIndex(),
focused.getColumnIndex());
}
});
}
private void updateLabel(VLabel label, String output, int object,
int column) {
String coords = "(" + object + ", " + column + ")";
label.setText(coords + " " + output);
}
private void createDetailsMenu() {
String[] menupath = new String[] { "Component", "Row details" };
addMenuCommand("Set generator", new ScheduledCommand() {
@Override
public void execute() {
grid.setDetailsGenerator(new DetailsGenerator() {
@Override
public Widget getDetails(int rowIndex) {
FlowPanel panel = new FlowPanel();
final Label label = new Label("Row: " + rowIndex + ".");
Button button = new Button("Button",
new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
label.setText("clicked");
}
});
panel.add(label);
panel.add(button);
return panel;
}
});
}
}, menupath);
addMenuCommand("Set faulty generator", new ScheduledCommand() {
@Override
public void execute() {
grid.setDetailsGenerator(new DetailsGenerator() {
@Override
public Widget getDetails(int rowIndex) {
throw new RuntimeException("This is by design.");
}
});
}
}, menupath);
addMenuCommand("Set empty generator", new ScheduledCommand() {
@Override
public void execute() {
grid.setDetailsGenerator(new DetailsGenerator() {
/*
* While this is functionally equivalent to the NULL
* generator, it's good to be explicit, since the behavior
* isn't strictly tied between them. NULL generator might be
* changed to render something different by default, and an
* empty generator might behave differently also in the
* future.
*/
@Override
public Widget getDetails(int rowIndex) {
return null;
}
});
}
}, menupath);
String[] togglemenupath = new String[] { menupath[0], menupath[1],
"Toggle details for..." };
for (int i : new int[] { 0, 1, 100, 200, 300, 400, 500, 600, 700, 800,
900, 999 }) {
final int rowIndex = i;
addMenuCommand("Row " + rowIndex, new ScheduledCommand() {
boolean visible = false;
@Override
public void execute() {
visible = !visible;
grid.setDetailsVisible(rowIndex, visible);
}
}, togglemenupath);
}
}
private static Logger getLogger() {
return Logger.getLogger(GridBasicClientFeaturesWidget.class.getName());
}
private void createSidebarMenu() {
String[] menupath = new String[] { "Component", "Sidebar" };
final List<MenuItem> customMenuItems = new ArrayList<>();
final List<MenuItemSeparator> separators = new ArrayList<>();
addMenuCommand("Add item to end", new ScheduledCommand() {
@Override
public void execute() {
MenuItem item = createSidebarMenuItem(customMenuItems.size());
customMenuItems.add(item);
grid.getSidebarMenu().addItem(item);
}
}, menupath);
addMenuCommand("Add item before index 1", new ScheduledCommand() {
@Override
public void execute() {
MenuItem item = createSidebarMenuItem(customMenuItems.size());
customMenuItems.add(item);
grid.getSidebarMenu().insertItem(item, 1);
}
}, menupath);
addMenuCommand("Remove last added item", new ScheduledCommand() {
@Override
public void execute() {
grid.getSidebarMenu().removeItem(
customMenuItems.remove(customMenuItems.size() - 1));
}
}, menupath);
addMenuCommand("Add separator to end", new ScheduledCommand() {
@Override
public void execute() {
MenuItemSeparator separator = new MenuItemSeparator();
separators.add(separator);
grid.getSidebarMenu().addSeparator(separator);
}
}, menupath);
addMenuCommand("Add separator before index 1", new ScheduledCommand() {
@Override
public void execute() {
MenuItemSeparator separator = new MenuItemSeparator();
separators.add(separator);
grid.getSidebarMenu().insertSeparator(separator, 1);
}
}, menupath);
addMenuCommand("Remove last added separator", new ScheduledCommand() {
@Override
public void execute() {
grid.getSidebarMenu().removeSeparator(
separators.remove(separators.size() - 1));
}
}, menupath);
addMenuCommand("Toggle sidebar visibility", new ScheduledCommand() {
@Override
public void execute() {
grid.setSidebarOpen(!grid.isSidebarOpen());
}
}, menupath);
addMenuCommand("Open sidebar and disable grid", new ScheduledCommand() {
@Override
public void execute() {
grid.setSidebarOpen(true);
Scheduler.get()
.scheduleFixedDelay(new Scheduler.RepeatingCommand() {
@Override
public boolean execute() {
if (grid.isSidebarOpen()) {
grid.setEnabled(false);
return false;
}
return true;
}
}, 250);
}
}, menupath);
}
private MenuItem createSidebarMenuItem(final int index) {
final MenuItem menuItem = new MenuItem("Custom menu item " + index,
new ScheduledCommand() {
@Override
public void execute() {
if (index % 2 == 0) {
grid.setSidebarOpen(false);
}
getLogger().info("Menu item " + index + " selected");
}
});
return menuItem;
}
}