You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridBasicClientFeaturesWidget.java 58KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tests.widgetset.client.v7.grid;
  17. import java.util.ArrayList;
  18. import java.util.Collections;
  19. import java.util.Date;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Random;
  24. import java.util.logging.Logger;
  25. import com.google.gwt.core.client.Scheduler;
  26. import com.google.gwt.core.client.Scheduler.ScheduledCommand;
  27. import com.google.gwt.dom.client.Style.Unit;
  28. import com.google.gwt.event.dom.client.ClickHandler;
  29. import com.google.gwt.event.dom.client.ContextMenuEvent;
  30. import com.google.gwt.event.dom.client.ContextMenuHandler;
  31. import com.google.gwt.event.shared.HandlerRegistration;
  32. import com.google.gwt.user.client.Event;
  33. import com.google.gwt.user.client.Timer;
  34. import com.google.gwt.user.client.Window;
  35. import com.google.gwt.user.client.ui.Button;
  36. import com.google.gwt.user.client.ui.Composite;
  37. import com.google.gwt.user.client.ui.FlowPanel;
  38. import com.google.gwt.user.client.ui.HTML;
  39. import com.google.gwt.user.client.ui.Label;
  40. import com.google.gwt.user.client.ui.MenuItem;
  41. import com.google.gwt.user.client.ui.MenuItemSeparator;
  42. import com.google.gwt.user.client.ui.TextBox;
  43. import com.google.gwt.user.client.ui.Widget;
  44. import com.vaadin.client.data.DataSource;
  45. import com.vaadin.client.data.DataSource.RowHandle;
  46. import com.vaadin.client.ui.VLabel;
  47. import com.vaadin.tests.widgetset.client.v7.grid.GridBasicClientFeaturesWidget.Data;
  48. import com.vaadin.v7.client.renderers.DateRenderer;
  49. import com.vaadin.v7.client.renderers.HtmlRenderer;
  50. import com.vaadin.v7.client.renderers.NumberRenderer;
  51. import com.vaadin.v7.client.renderers.Renderer;
  52. import com.vaadin.v7.client.renderers.TextRenderer;
  53. import com.vaadin.v7.client.widget.grid.CellReference;
  54. import com.vaadin.v7.client.widget.grid.CellStyleGenerator;
  55. import com.vaadin.v7.client.widget.grid.DetailsGenerator;
  56. import com.vaadin.v7.client.widget.grid.EditorHandler;
  57. import com.vaadin.v7.client.widget.grid.EventCellReference;
  58. import com.vaadin.v7.client.widget.grid.RendererCellReference;
  59. import com.vaadin.v7.client.widget.grid.RowReference;
  60. import com.vaadin.v7.client.widget.grid.RowStyleGenerator;
  61. import com.vaadin.v7.client.widget.grid.datasources.ListDataSource;
  62. import com.vaadin.v7.client.widget.grid.datasources.ListSorter;
  63. import com.vaadin.v7.client.widget.grid.events.BodyKeyDownHandler;
  64. import com.vaadin.v7.client.widget.grid.events.BodyKeyPressHandler;
  65. import com.vaadin.v7.client.widget.grid.events.BodyKeyUpHandler;
  66. import com.vaadin.v7.client.widget.grid.events.ColumnReorderEvent;
  67. import com.vaadin.v7.client.widget.grid.events.ColumnReorderHandler;
  68. import com.vaadin.v7.client.widget.grid.events.ColumnVisibilityChangeEvent;
  69. import com.vaadin.v7.client.widget.grid.events.ColumnVisibilityChangeHandler;
  70. import com.vaadin.v7.client.widget.grid.events.FooterKeyDownHandler;
  71. import com.vaadin.v7.client.widget.grid.events.FooterKeyPressHandler;
  72. import com.vaadin.v7.client.widget.grid.events.FooterKeyUpHandler;
  73. import com.vaadin.v7.client.widget.grid.events.GridKeyDownEvent;
  74. import com.vaadin.v7.client.widget.grid.events.GridKeyPressEvent;
  75. import com.vaadin.v7.client.widget.grid.events.GridKeyUpEvent;
  76. import com.vaadin.v7.client.widget.grid.events.HeaderKeyDownHandler;
  77. import com.vaadin.v7.client.widget.grid.events.HeaderKeyPressHandler;
  78. import com.vaadin.v7.client.widget.grid.events.HeaderKeyUpHandler;
  79. import com.vaadin.v7.client.widget.grid.selection.SelectionModel;
  80. import com.vaadin.v7.client.widget.grid.selection.SelectionModel.None;
  81. import com.vaadin.v7.client.widgets.Grid;
  82. import com.vaadin.v7.client.widgets.Grid.Column;
  83. import com.vaadin.v7.client.widgets.Grid.FooterRow;
  84. import com.vaadin.v7.client.widgets.Grid.HeaderRow;
  85. import com.vaadin.v7.client.widgets.Grid.SelectionMode;
  86. import com.vaadin.v7.shared.ui.grid.ScrollDestination;
  87. /**
  88. * Grid basic client features test application.
  89. *
  90. * @since
  91. * @author Vaadin Ltd
  92. */
  93. public class GridBasicClientFeaturesWidget
  94. extends PureGWTTestApplication<Grid<List<Data>>> {
  95. public static final String ROW_STYLE_GENERATOR_NONE = "None";
  96. public static final String ROW_STYLE_GENERATOR_ROW_INDEX = "Row numbers";
  97. public static final String ROW_STYLE_GENERATOR_EVERY_THIRD = "Every third";
  98. public static final String CELL_STYLE_GENERATOR_NONE = "None";
  99. public static final String CELL_STYLE_GENERATOR_SIMPLE = "Simple";
  100. public static final String CELL_STYLE_GENERATOR_COL_INDEX = "Column index";
  101. public static enum Renderers {
  102. TEXT_RENDERER, HTML_RENDERER, NUMBER_RENDERER, DATE_RENDERER;
  103. }
  104. private class TestEditorHandler implements EditorHandler<List<Data>> {
  105. private Map<Grid.Column<?, ?>, TextBox> widgets = new HashMap<>();
  106. private Label log = new Label();
  107. {
  108. log.addStyleName("grid-editor-log");
  109. addSouth(log, 20);
  110. }
  111. @Override
  112. public void bind(EditorRequest<List<Data>> request) {
  113. List<Data> rowData = ds.getRow(request.getRowIndex());
  114. boolean hasSelectionColumn = !(grid
  115. .getSelectionModel() instanceof None);
  116. for (int i = 0; i < rowData.size(); i++) {
  117. int columnIndex = hasSelectionColumn ? i + 1 : i;
  118. getWidget(columnIndex).setText(rowData.get(i).value.toString());
  119. }
  120. request.success();
  121. }
  122. @Override
  123. public void cancel(EditorRequest<List<Data>> request) {
  124. log.setText("Row " + request.getRowIndex() + " edit cancelled");
  125. }
  126. @Override
  127. public void save(EditorRequest<List<Data>> request) {
  128. if (secondEditorError) {
  129. request.failure("Syntethic fail of editor in column 2. "
  130. + "This message is so long that it doesn't fit into its box",
  131. Collections.<Column<?, List<Data>>> singleton(
  132. grid.getColumn(2)));
  133. return;
  134. }
  135. try {
  136. log.setText("Row " + request.getRowIndex() + " edit committed");
  137. List<Data> rowData = ds.getRow(request.getRowIndex());
  138. int i = 0;
  139. for (; i < COLUMNS - MANUALLY_FORMATTED_COLUMNS; i++) {
  140. rowData.get(i).value = getWidget(i).getText();
  141. }
  142. rowData.get(i).value = Integer
  143. .valueOf(getWidget(i++).getText());
  144. rowData.get(i).value = new Date(getWidget(i++).getText());
  145. rowData.get(i).value = getWidget(i++).getText();
  146. rowData.get(i).value = Integer
  147. .valueOf(getWidget(i++).getText());
  148. rowData.get(i).value = Integer
  149. .valueOf(getWidget(i++).getText());
  150. // notify data source of changes
  151. ds.asList().set(request.getRowIndex(), rowData);
  152. request.success();
  153. } catch (Exception e) {
  154. Logger.getLogger(getClass().getName()).warning(e.toString());
  155. request.failure(null, null);
  156. }
  157. }
  158. @Override
  159. public TextBox getWidget(Grid.Column<?, List<Data>> column) {
  160. if (grid.getColumns().indexOf(column) == 0
  161. && !(grid.getSelectionModel() instanceof None)) {
  162. return null;
  163. }
  164. TextBox w = widgets.get(column);
  165. if (w == null) {
  166. w = new TextBox();
  167. w.getElement().getStyle().setMargin(0, Unit.PX);
  168. widgets.put(column, w);
  169. }
  170. return w;
  171. }
  172. private TextBox getWidget(int i) {
  173. return getWidget(grid.getColumn(i));
  174. }
  175. }
  176. private static final int MANUALLY_FORMATTED_COLUMNS = 5;
  177. public static final int COLUMNS = 12;
  178. public static final int ROWS = 1000;
  179. private final Grid<List<Data>> grid;
  180. private List<List<Data>> data;
  181. private final ListDataSource<List<Data>> ds;
  182. private final ListSorter<List<Data>> sorter;
  183. private boolean secondEditorError = false;
  184. /**
  185. * Our basic data object
  186. */
  187. public static final class Data {
  188. Object value;
  189. }
  190. /**
  191. * @since
  192. * @return
  193. */
  194. private List<List<Data>> createData(int rowCount) {
  195. List<List<Data>> dataList = new ArrayList<>();
  196. Random rand = new Random();
  197. rand.setSeed(13334);
  198. long timestamp = 0;
  199. for (int row = 0; row < rowCount; row++) {
  200. List<Data> datarow = createDataRow(COLUMNS);
  201. dataList.add(datarow);
  202. Data d;
  203. int col = 0;
  204. for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; ++col) {
  205. d = datarow.get(col);
  206. d.value = "(" + row + ", " + col + ")";
  207. }
  208. d = datarow.get(col++);
  209. d.value = Integer.valueOf(row);
  210. d = datarow.get(col++);
  211. d.value = new Date(timestamp);
  212. timestamp += 91250000; // a bit over a day, just to get
  213. // variation
  214. d = datarow.get(col++);
  215. d.value = "<b>" + row + "</b>";
  216. d = datarow.get(col++);
  217. d.value = Integer.valueOf(rand.nextInt());
  218. d = datarow.get(col++);
  219. d.value = Integer.valueOf(rand.nextInt(5));
  220. }
  221. return dataList;
  222. }
  223. /**
  224. * Convenience method for creating a list of Data objects to be used as a
  225. * Row in the data source
  226. *
  227. * @param cols
  228. * number of columns (items) to include in the row
  229. * @return
  230. */
  231. private List<Data> createDataRow(int cols) {
  232. List<Data> list = new ArrayList<>(cols);
  233. for (int i = 0; i < cols; ++i) {
  234. list.add(new Data());
  235. }
  236. return list;
  237. }
  238. @SuppressWarnings("unchecked")
  239. public GridBasicClientFeaturesWidget() {
  240. super(new Grid<List<Data>>());
  241. // Initialize data source
  242. data = createData(ROWS);
  243. ds = new ListDataSource<>(data);
  244. grid = getTestedWidget();
  245. grid.getElement().setId("testComponent");
  246. grid.setDataSource(ds);
  247. grid.addSelectAllHandler(ds.getSelectAllHandler());
  248. grid.setSelectionMode(SelectionMode.NONE);
  249. grid.setEditorHandler(new TestEditorHandler());
  250. sorter = new ListSorter<>(grid);
  251. // Create a bunch of grid columns
  252. // Data source layout:
  253. // text (String) * (COLUMNS - MANUALLY_FORMATTED_COLUMNS + 1) |
  254. // rownumber (Integer) | some date (Date) | row number as HTML (String)
  255. // | random value (Integer)
  256. int col = 0;
  257. // Text times COLUMNS - MANUALLY_FORMATTED_COLUMNS
  258. for (col = 0; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; ++col) {
  259. final int c = col;
  260. Grid.Column<String, List<Data>> column = new Grid.Column<String, List<Data>>(
  261. createRenderer(Renderers.TEXT_RENDERER)) {
  262. @Override
  263. public String getValue(List<Data> row) {
  264. return (String) row.get(c).value;
  265. }
  266. };
  267. column.setWidth(50 + c * 25);
  268. column.setHeaderCaption("Header (0," + c + ")");
  269. grid.addColumn(column);
  270. }
  271. // Integer row number
  272. {
  273. final int c = col++;
  274. Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>(
  275. createRenderer(Renderers.NUMBER_RENDERER)) {
  276. @Override
  277. public Integer getValue(List<Data> row) {
  278. return (Integer) row.get(c).value;
  279. }
  280. };
  281. grid.addColumn(column);
  282. column.setHeaderCaption("Header (0," + c + ")");
  283. }
  284. // Some date
  285. {
  286. final int c = col++;
  287. Grid.Column<Date, List<Data>> column = new Grid.Column<Date, List<Data>>(
  288. createRenderer(Renderers.DATE_RENDERER)) {
  289. @Override
  290. public Date getValue(List<Data> row) {
  291. return (Date) row.get(c).value;
  292. }
  293. };
  294. grid.addColumn(column);
  295. column.setHeaderCaption("Header (0," + c + ")");
  296. }
  297. // Row number as a HTML string
  298. {
  299. final int c = col++;
  300. Grid.Column<String, List<Data>> column = new Grid.Column<String, List<Data>>(
  301. createRenderer(Renderers.HTML_RENDERER)) {
  302. @Override
  303. public String getValue(List<Data> row) {
  304. return (String) row.get(c).value;
  305. }
  306. };
  307. grid.addColumn(column);
  308. column.setHeaderCaption("Header (0," + c + ")");
  309. }
  310. // Random integer value
  311. {
  312. final int c = col++;
  313. Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>(
  314. createRenderer(Renderers.NUMBER_RENDERER)) {
  315. @Override
  316. public Integer getValue(List<Data> row) {
  317. return (Integer) row.get(c).value;
  318. }
  319. };
  320. grid.addColumn(column);
  321. column.setHeaderCaption("Header (0," + c + ")");
  322. }
  323. // Random integer value between 0 and 5
  324. {
  325. final int c = col++;
  326. Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>(
  327. createRenderer(Renderers.NUMBER_RENDERER)) {
  328. @Override
  329. public Integer getValue(List<Data> row) {
  330. return (Integer) row.get(c).value;
  331. }
  332. };
  333. grid.addColumn(column);
  334. column.setHeaderCaption("Header (0," + c + ")");
  335. }
  336. grid.getColumn(3).setEditable(false);
  337. HeaderRow row = grid.getDefaultHeaderRow();
  338. for (int i = 0; i < col; ++i) {
  339. String caption = "Header (0," + i + ")";
  340. Grid.Column<?, ?> column = grid.getColumn(i);
  341. // Lets use some different cell types
  342. if (i % 3 == 0) {
  343. // No-op
  344. } else if (i % 2 == 0) {
  345. row.getCell(column).setHtml("<b>" + caption + "</b>");
  346. } else {
  347. row.getCell(column).setWidget(new HTML(caption));
  348. }
  349. }
  350. ++headerCounter;
  351. //
  352. // Populate the menu
  353. //
  354. createStateMenu();
  355. createColumnsMenu();
  356. createHeaderMenu();
  357. createFooterMenu();
  358. createEditorMenu();
  359. createInternalsMenu();
  360. createDataSourceMenu();
  361. createDetailsMenu();
  362. createSidebarMenu();
  363. grid.getElement().getStyle().setZIndex(0);
  364. //
  365. // Composite wrapping for grid.
  366. //
  367. boolean isComposite = Window.Location.getParameter("composite") != null;
  368. if (isComposite) {
  369. addNorth(new Composite() {
  370. {
  371. initWidget(grid);
  372. }
  373. }, 400);
  374. } else {
  375. addNorth(grid, 400);
  376. }
  377. createKeyHandlers();
  378. }
  379. private void createInternalsMenu() {
  380. String[] listenersPath = { "Component", "Internals", "Listeners" };
  381. final Label label = new Label();
  382. addSouth(label, 20);
  383. addMenuCommand("Add scroll listener", new ScheduledCommand() {
  384. private HandlerRegistration scrollHandler = null;
  385. @Override
  386. public void execute() {
  387. if (scrollHandler != null) {
  388. return;
  389. }
  390. scrollHandler = grid.addScrollHandler(event -> {
  391. final Grid<?> grid = (Grid<?>) event.getSource();
  392. label.setText("scrollTop: " + grid.getScrollTop()
  393. + ", scrollLeft: " + grid.getScrollLeft());
  394. });
  395. }
  396. }, listenersPath);
  397. addMenuCommand("Add ColumnReorder listener", new ScheduledCommand() {
  398. private HandlerRegistration columnReorderHandler = null;
  399. @Override
  400. public void execute() {
  401. if (columnReorderHandler != null) {
  402. return;
  403. }
  404. final Label columnOrderLabel = new Label();
  405. columnOrderLabel.getElement().setId("columnreorder");
  406. addLineEnd(columnOrderLabel, 300);
  407. columnReorderHandler = grid.addColumnReorderHandler(
  408. new ColumnReorderHandler<List<Data>>() {
  409. private int eventIndex = 0;
  410. @Override
  411. public void onColumnReorder(
  412. ColumnReorderEvent<List<Data>> event) {
  413. columnOrderLabel.getElement().setAttribute(
  414. "columns", "" + (++eventIndex));
  415. }
  416. });
  417. }
  418. }, listenersPath);
  419. addMenuCommand("Add Column Visibility Change listener",
  420. new ScheduledCommand() {
  421. private HandlerRegistration columnVisibilityHandler = null;
  422. @Override
  423. public void execute() {
  424. if (columnVisibilityHandler != null) {
  425. return;
  426. }
  427. final Label columnOrderLabel = new Label();
  428. columnOrderLabel.getElement().setId("columnvisibility");
  429. addLineEnd(columnOrderLabel, 250);
  430. ColumnVisibilityChangeHandler handler = new ColumnVisibilityChangeHandler<List<Data>>() {
  431. private int eventIndex = 0;
  432. @Override
  433. public void onVisibilityChange(
  434. ColumnVisibilityChangeEvent<List<Data>> event) {
  435. columnOrderLabel.getElement().setAttribute(
  436. "counter", "" + (++eventIndex));
  437. columnOrderLabel.getElement().setAttribute(
  438. "useroriginated", (Boolean.toString(
  439. event.isUserOriginated())));
  440. columnOrderLabel.getElement().setAttribute(
  441. "ishidden",
  442. (Boolean.toString(event.isHidden())));
  443. columnOrderLabel.getElement().setAttribute(
  444. "columnindex", "" + grid.getColumns()
  445. .indexOf(event.getColumn()));
  446. }
  447. };
  448. columnVisibilityHandler = grid
  449. .addColumnVisibilityChangeHandler(handler);
  450. }
  451. }, listenersPath);
  452. addMenuCommand("Add context menu listener", new ScheduledCommand() {
  453. HandlerRegistration handler = null;
  454. ContextMenuHandler contextMenuHandler = event -> {
  455. event.preventDefault();
  456. final String location;
  457. EventCellReference<?> cellRef = grid.getEventCell();
  458. if (cellRef.isHeader()) {
  459. location = "header";
  460. } else if (cellRef.isBody()) {
  461. location = "body";
  462. } else if (cellRef.isFooter()) {
  463. location = "footer";
  464. } else {
  465. location = "somewhere";
  466. }
  467. getLogger().info(
  468. "Prevented opening a context menu in grid " + location);
  469. };
  470. @Override
  471. public void execute() {
  472. if (handler != null) {
  473. grid.unsinkEvents(Event.ONCONTEXTMENU);
  474. handler.removeHandler();
  475. } else {
  476. grid.sinkEvents(Event.ONCONTEXTMENU);
  477. handler = grid.addDomHandler(contextMenuHandler,
  478. ContextMenuEvent.getType());
  479. }
  480. }
  481. }, listenersPath);
  482. }
  483. private void createStateMenu() {
  484. String[] selectionModePath = { "Component", "State", "Selection mode" };
  485. String[] primaryStyleNamePath = { "Component", "State",
  486. "Primary Stylename" };
  487. String[] rowStyleGeneratorNamePath = { "Component", "State",
  488. "Row style generator" };
  489. String[] cellStyleGeneratorNamePath = { "Component", "State",
  490. "Cell style generator" };
  491. addMenuCommand("multi", new ScheduledCommand() {
  492. @Override
  493. public void execute() {
  494. grid.setSelectionMode(SelectionMode.MULTI);
  495. }
  496. }, selectionModePath);
  497. addMenuCommand("single", new ScheduledCommand() {
  498. @Override
  499. public void execute() {
  500. grid.setSelectionMode(SelectionMode.SINGLE);
  501. }
  502. }, selectionModePath);
  503. addMenuCommand("single (no deselect)", new ScheduledCommand() {
  504. @Override
  505. public void execute() {
  506. grid.setSelectionMode(SelectionMode.SINGLE);
  507. ((SelectionModel.Single<?>) grid.getSelectionModel())
  508. .setDeselectAllowed(false);
  509. }
  510. }, selectionModePath);
  511. addMenuCommand("none", new ScheduledCommand() {
  512. @Override
  513. public void execute() {
  514. grid.setSelectionMode(SelectionMode.NONE);
  515. }
  516. }, selectionModePath);
  517. addMenuCommand("v-grid", new ScheduledCommand() {
  518. @Override
  519. public void execute() {
  520. grid.setStylePrimaryName("v-grid");
  521. }
  522. }, primaryStyleNamePath);
  523. addMenuCommand("v-escalator", new ScheduledCommand() {
  524. @Override
  525. public void execute() {
  526. grid.setStylePrimaryName("v-escalator");
  527. }
  528. }, primaryStyleNamePath);
  529. addMenuCommand("v-custom-style", new ScheduledCommand() {
  530. @Override
  531. public void execute() {
  532. grid.setStylePrimaryName("v-custom-style");
  533. }
  534. }, primaryStyleNamePath);
  535. addMenuCommand("Edit and refresh Row 0", new ScheduledCommand() {
  536. @Override
  537. public void execute() {
  538. DataSource<List<Data>> ds = grid.getDataSource();
  539. RowHandle<List<Data>> rowHandle = ds.getHandle(ds.getRow(0));
  540. rowHandle.getRow().get(0).value = "Foo";
  541. rowHandle.updateRow();
  542. }
  543. }, "Component", "State");
  544. addMenuCommand("Delayed edit of Row 0", new ScheduledCommand() {
  545. @Override
  546. public void execute() {
  547. DataSource<List<Data>> ds = grid.getDataSource();
  548. final RowHandle<List<Data>> rowHandle = ds
  549. .getHandle(ds.getRow(0));
  550. new Timer() {
  551. @Override
  552. public void run() {
  553. rowHandle.getRow().get(0).value = "Bar";
  554. rowHandle.updateRow();
  555. }
  556. }.schedule(5000);
  557. }
  558. }, "Component", "State");
  559. addMenuCommand(ROW_STYLE_GENERATOR_NONE, new ScheduledCommand() {
  560. @Override
  561. public void execute() {
  562. grid.setRowStyleGenerator(null);
  563. }
  564. }, rowStyleGeneratorNamePath);
  565. addMenuCommand(ROW_STYLE_GENERATOR_EVERY_THIRD, new ScheduledCommand() {
  566. @Override
  567. public void execute() {
  568. grid.setRowStyleGenerator(new RowStyleGenerator<List<Data>>() {
  569. @Override
  570. public String getStyle(
  571. RowReference<List<Data>> rowReference) {
  572. if (rowReference.getRowIndex() % 3 == 0) {
  573. return "third";
  574. } else {
  575. // First manual col is integer
  576. Integer value = (Integer) rowReference.getRow().get(
  577. COLUMNS - MANUALLY_FORMATTED_COLUMNS).value;
  578. return value.toString();
  579. }
  580. }
  581. });
  582. }
  583. }, rowStyleGeneratorNamePath);
  584. addMenuCommand(ROW_STYLE_GENERATOR_ROW_INDEX, new ScheduledCommand() {
  585. @Override
  586. public void execute() {
  587. grid.setRowStyleGenerator(new RowStyleGenerator<List<Data>>() {
  588. @Override
  589. public String getStyle(
  590. RowReference<List<Data>> rowReference) {
  591. return Integer.toString(rowReference.getRowIndex());
  592. }
  593. });
  594. }
  595. }, rowStyleGeneratorNamePath);
  596. addMenuCommand(CELL_STYLE_GENERATOR_NONE, new ScheduledCommand() {
  597. @Override
  598. public void execute() {
  599. grid.setCellStyleGenerator(null);
  600. }
  601. }, cellStyleGeneratorNamePath);
  602. addMenuCommand(CELL_STYLE_GENERATOR_SIMPLE, new ScheduledCommand() {
  603. @Override
  604. public void execute() {
  605. grid.setCellStyleGenerator(
  606. new CellStyleGenerator<List<Data>>() {
  607. @Override
  608. public String getStyle(
  609. CellReference<List<Data>> cellReference) {
  610. Grid.Column<?, List<Data>> column = cellReference
  611. .getColumn();
  612. if (column == grid.getColumn(2)) {
  613. return "two";
  614. } else if (column == grid.getColumn(
  615. COLUMNS - MANUALLY_FORMATTED_COLUMNS)) {
  616. // First manual col is integer
  617. Integer value = (Integer) column
  618. .getValue(cellReference.getRow());
  619. return value.toString();
  620. } else {
  621. return null;
  622. }
  623. }
  624. });
  625. }
  626. }, cellStyleGeneratorNamePath);
  627. addMenuCommand(CELL_STYLE_GENERATOR_COL_INDEX, new ScheduledCommand() {
  628. @Override
  629. public void execute() {
  630. grid.setCellStyleGenerator(
  631. new CellStyleGenerator<List<Data>>() {
  632. @Override
  633. public String getStyle(
  634. CellReference<List<Data>> cellReference) {
  635. return cellReference.getRowIndex() + "_"
  636. + grid.getColumns().indexOf(
  637. cellReference.getColumn());
  638. }
  639. });
  640. }
  641. }, cellStyleGeneratorNamePath);
  642. for (int i = -1; i <= COLUMNS; i++) {
  643. final int index = i;
  644. // Including dummy "columns" prefix because TB fails to select item
  645. // if it's too narrow
  646. addMenuCommand(Integer.toString(index) + " columns",
  647. new ScheduledCommand() {
  648. @Override
  649. public void execute() {
  650. grid.setFrozenColumnCount(index);
  651. }
  652. }, "Component", "State", "Frozen column count");
  653. }
  654. addMenuCommand("Enabled", new ScheduledCommand() {
  655. @Override
  656. public void execute() {
  657. grid.setEnabled(!grid.isEnabled());
  658. }
  659. }, "Component", "State");
  660. addMenuCommand("Reverse grid columns", new ScheduledCommand() {
  661. @Override
  662. public void execute() {
  663. List<Column> columns = new ArrayList<>(grid.getColumns());
  664. Collections.reverse(columns);
  665. grid.setColumnOrder(
  666. columns.toArray(new Column[columns.size()]));
  667. }
  668. }, "Component", "State");
  669. addMenuCommand("Column Reordering", new ScheduledCommand() {
  670. @Override
  671. public void execute() {
  672. grid.setColumnReorderingAllowed(
  673. !grid.isColumnReorderingAllowed());
  674. }
  675. }, "Component", "State");
  676. addMenuCommand("250px", new ScheduledCommand() {
  677. @Override
  678. public void execute() {
  679. grid.setWidth("250px");
  680. }
  681. }, "Component", "State", "Width");
  682. addMenuCommand("500px", new ScheduledCommand() {
  683. @Override
  684. public void execute() {
  685. grid.setWidth("500px");
  686. }
  687. }, "Component", "State", "Width");
  688. addMenuCommand("750px", new ScheduledCommand() {
  689. @Override
  690. public void execute() {
  691. grid.setWidth("750px");
  692. }
  693. }, "Component", "State", "Width");
  694. addMenuCommand("1000px", new ScheduledCommand() {
  695. @Override
  696. public void execute() {
  697. grid.setWidth("1000px");
  698. }
  699. }, "Component", "State", "Width");
  700. createScrollToRowMenu();
  701. }
  702. private void createScrollToRowMenu() {
  703. String[] menupath = { "Component", "State", "Scroll to...", null };
  704. for (int i = 0; i < ROWS; i += 100) {
  705. menupath[3] = "Row " + i + "...";
  706. for (final ScrollDestination scrollDestination : ScrollDestination
  707. .values()) {
  708. final int row = i;
  709. addMenuCommand("Destination " + scrollDestination,
  710. new ScheduledCommand() {
  711. @Override
  712. public void execute() {
  713. grid.scrollToRow(row, scrollDestination);
  714. }
  715. }, menupath);
  716. }
  717. }
  718. int i = ROWS - 1;
  719. menupath[3] = "Row " + i + "...";
  720. for (final ScrollDestination scrollDestination : ScrollDestination
  721. .values()) {
  722. final int row = i;
  723. addMenuCommand("Destination " + scrollDestination,
  724. new ScheduledCommand() {
  725. @Override
  726. public void execute() {
  727. grid.scrollToRow(row, scrollDestination);
  728. }
  729. }, menupath);
  730. }
  731. }
  732. private void createColumnsMenu() {
  733. for (int i = 0; i < COLUMNS; i++) {
  734. final int index = i;
  735. final Grid.Column<?, List<Data>> column = grid.getColumn(index);
  736. addMenuCommand("Sortable", new ScheduledCommand() {
  737. @Override
  738. public void execute() {
  739. column.setSortable(!column.isSortable());
  740. }
  741. }, "Component", "Columns", "Column " + i);
  742. addMenuCommand("Hidden", new ScheduledCommand() {
  743. @Override
  744. public void execute() {
  745. column.setHidden(!column.isHidden());
  746. }
  747. }, "Component", "Columns", "Column " + i);
  748. addMenuCommand("Hidable", new ScheduledCommand() {
  749. @Override
  750. public void execute() {
  751. column.setHidable(!column.isHidable());
  752. }
  753. }, "Component", "Columns", "Column " + i);
  754. addMenuCommand("auto", new ScheduledCommand() {
  755. @Override
  756. public void execute() {
  757. column.setWidth(-1);
  758. }
  759. }, "Component", "Columns", "Column " + i, "Width");
  760. addMenuCommand("50px", new ScheduledCommand() {
  761. @Override
  762. public void execute() {
  763. column.setWidth(50);
  764. }
  765. }, "Component", "Columns", "Column " + i, "Width");
  766. addMenuCommand("200px", new ScheduledCommand() {
  767. @Override
  768. public void execute() {
  769. column.setWidth(200);
  770. }
  771. }, "Component", "Columns", "Column " + i, "Width");
  772. // Header types
  773. addMenuCommand("Text Header", new ScheduledCommand() {
  774. @Override
  775. public void execute() {
  776. column.setHeaderCaption("Text Header");
  777. }
  778. }, "Component", "Columns", "Column " + i, "Header Type");
  779. addMenuCommand("HTML Header", new ScheduledCommand() {
  780. @Override
  781. public void execute() {
  782. grid.getHeaderRow(0).getCell(column)
  783. .setHtml("<b>HTML Header</b>");
  784. }
  785. }, "Component", "Columns", "Column " + i, "Header Type");
  786. addMenuCommand("Widget Header", new ScheduledCommand() {
  787. @Override
  788. public void execute() {
  789. final Button button = new Button("Button Header");
  790. button.addClickHandler(event -> button.setText("Clicked"));
  791. grid.getHeaderRow(0).getCell(column).setWidget(button);
  792. }
  793. }, "Component", "Columns", "Column " + i, "Header Type");
  794. // Footer types
  795. addMenuCommand("Text Footer", new ScheduledCommand() {
  796. @Override
  797. public void execute() {
  798. grid.getFooterRow(0).getCell(column).setText("Text Footer");
  799. }
  800. }, "Component", "Columns", "Column " + i, "Footer Type");
  801. addMenuCommand("HTML Footer", new ScheduledCommand() {
  802. @Override
  803. public void execute() {
  804. grid.getFooterRow(0).getCell(column)
  805. .setHtml("<b>HTML Footer</b>");
  806. }
  807. }, "Component", "Columns", "Column " + i, "Footer Type");
  808. addMenuCommand("Widget Footer", new ScheduledCommand() {
  809. @Override
  810. public void execute() {
  811. final Button button = new Button("Button Footer");
  812. button.addClickHandler(event -> button.setText("Clicked"));
  813. grid.getFooterRow(0).getCell(column).setWidget(button);
  814. }
  815. }, "Component", "Columns", "Column " + i, "Footer Type");
  816. // Renderer throwing exceptions
  817. addMenuCommand("Broken renderer", new ScheduledCommand() {
  818. @Override
  819. public void execute() {
  820. final Renderer<Object> originalRenderer = (Renderer<Object>) column
  821. .getRenderer();
  822. column.setRenderer(new Renderer<Object>() {
  823. @Override
  824. public void render(RendererCellReference cell,
  825. Object data) {
  826. if (cell.getRowIndex() == cell.getColumnIndex()) {
  827. throw new RuntimeException("I'm broken");
  828. }
  829. originalRenderer.render(cell, data);
  830. }
  831. });
  832. }
  833. }, "Component", "Columns", "Column " + i);
  834. addMenuCommand("Move column left", new ScheduledCommand() {
  835. @SuppressWarnings("unchecked")
  836. @Override
  837. public void execute() {
  838. List<Column<?, List<Data>>> cols = grid.getColumns();
  839. List<Column> reordered = new ArrayList<>(cols);
  840. final int index = cols.indexOf(column);
  841. if (index == 0) {
  842. Column<?, List<Data>> col = reordered.remove(0);
  843. reordered.add(col);
  844. } else {
  845. Column<?, List<Data>> col = reordered.remove(index);
  846. reordered.add(index - 1, col);
  847. }
  848. grid.setColumnOrder(
  849. reordered.toArray(new Column[reordered.size()]));
  850. }
  851. }, "Component", "Columns", "Column " + i);
  852. }
  853. }
  854. private int headerCounter = 0;
  855. private int footerCounter = 0;
  856. private void setHeaderTexts(HeaderRow row) {
  857. for (int i = 0; i < COLUMNS; ++i) {
  858. String caption = "Header (" + headerCounter + "," + i + ")";
  859. // Lets use some different cell types
  860. if (i % 3 == 0) {
  861. row.getCell(grid.getColumn(i)).setText(caption);
  862. } else if (i % 2 == 0) {
  863. row.getCell(grid.getColumn(i))
  864. .setHtml("<b>" + caption + "</b>");
  865. } else {
  866. row.getCell(grid.getColumn(i)).setWidget(new HTML(caption));
  867. }
  868. }
  869. headerCounter++;
  870. }
  871. private void setFooterTexts(FooterRow row) {
  872. for (int i = 0; i < COLUMNS; ++i) {
  873. String caption = "Footer (" + footerCounter + "," + i + ")";
  874. // Lets use some different cell types
  875. if (i % 3 == 0) {
  876. row.getCell(grid.getColumn(i)).setText(caption);
  877. } else if (i % 2 == 0) {
  878. row.getCell(grid.getColumn(i))
  879. .setHtml("<b>" + caption + "</b>");
  880. } else {
  881. row.getCell(grid.getColumn(i)).setWidget(new HTML(caption));
  882. }
  883. }
  884. footerCounter++;
  885. }
  886. private void createHeaderMenu() {
  887. final String[] menuPath = { "Component", "Header" };
  888. addMenuCommand("Visible", new ScheduledCommand() {
  889. @Override
  890. public void execute() {
  891. grid.setHeaderVisible(!grid.isHeaderVisible());
  892. }
  893. }, menuPath);
  894. addMenuCommand("Top", new ScheduledCommand() {
  895. @Override
  896. public void execute() {
  897. grid.setDefaultHeaderRow(grid.getHeaderRow(0));
  898. }
  899. }, "Component", "Header", "Default row");
  900. addMenuCommand("Bottom", new ScheduledCommand() {
  901. @Override
  902. public void execute() {
  903. grid.setDefaultHeaderRow(
  904. grid.getHeaderRow(grid.getHeaderRowCount() - 1));
  905. }
  906. }, "Component", "Header", "Default row");
  907. addMenuCommand("Unset", new ScheduledCommand() {
  908. @Override
  909. public void execute() {
  910. grid.setDefaultHeaderRow(null);
  911. }
  912. }, "Component", "Header", "Default row");
  913. addMenuCommand("Prepend row", new ScheduledCommand() {
  914. @Override
  915. public void execute() {
  916. configureHeaderRow(grid.prependHeaderRow());
  917. }
  918. }, menuPath);
  919. addMenuCommand("Append row", new ScheduledCommand() {
  920. @Override
  921. public void execute() {
  922. configureHeaderRow(grid.appendHeaderRow());
  923. }
  924. }, menuPath);
  925. addMenuCommand("Remove top row", new ScheduledCommand() {
  926. @Override
  927. public void execute() {
  928. grid.removeHeaderRow(0);
  929. }
  930. }, menuPath);
  931. addMenuCommand("Remove bottom row", new ScheduledCommand() {
  932. @Override
  933. public void execute() {
  934. grid.removeHeaderRow(grid.getHeaderRowCount() - 1);
  935. }
  936. }, menuPath);
  937. }
  938. private void configureHeaderRow(final HeaderRow row) {
  939. setHeaderTexts(row);
  940. String rowTitle = "Row " + grid.getHeaderRowCount();
  941. final String[] menuPath = { "Component", "Header", rowTitle };
  942. addMenuCommand("Join column cells 0, 1", new ScheduledCommand() {
  943. @Override
  944. public void execute() {
  945. row.join(row.getCell(grid.getColumn(0)),
  946. row.getCell(grid.getColumn(1)))
  947. .setText("Join column cells 0, 1");
  948. }
  949. }, menuPath);
  950. addMenuCommand("Join columns 1, 2", new ScheduledCommand() {
  951. @Override
  952. public void execute() {
  953. row.join(grid.getColumn(1), grid.getColumn(2))
  954. .setText("Join columns 1, 2");
  955. ;
  956. }
  957. }, menuPath);
  958. addMenuCommand("Join columns 3, 4, 5", new ScheduledCommand() {
  959. @Override
  960. public void execute() {
  961. row.join(grid.getColumn(3), grid.getColumn(4),
  962. grid.getColumn(5)).setText("Join columns 3, 4, 5");
  963. }
  964. }, menuPath);
  965. addMenuCommand("Join all columns", new ScheduledCommand() {
  966. @Override
  967. public void execute() {
  968. row.join(grid.getColumns()
  969. .toArray(new Grid.Column[grid.getColumnCount()]))
  970. .setText("Join all columns");
  971. ;
  972. }
  973. }, menuPath);
  974. }
  975. private void createFooterMenu() {
  976. final String[] menuPath = { "Component", "Footer" };
  977. addMenuCommand("Visible", new ScheduledCommand() {
  978. @Override
  979. public void execute() {
  980. grid.setFooterVisible(!grid.isFooterVisible());
  981. }
  982. }, menuPath);
  983. addMenuCommand("Prepend row", new ScheduledCommand() {
  984. @Override
  985. public void execute() {
  986. configureFooterRow(grid.prependFooterRow());
  987. }
  988. }, menuPath);
  989. addMenuCommand("Append row", new ScheduledCommand() {
  990. @Override
  991. public void execute() {
  992. configureFooterRow(grid.appendFooterRow());
  993. }
  994. }, menuPath);
  995. addMenuCommand("Remove top row", new ScheduledCommand() {
  996. @Override
  997. public void execute() {
  998. grid.removeFooterRow(0);
  999. }
  1000. }, menuPath);
  1001. addMenuCommand("Remove bottom row", new ScheduledCommand() {
  1002. @Override
  1003. public void execute() {
  1004. assert grid.getFooterRowCount() > 0;
  1005. grid.removeFooterRow(grid.getFooterRowCount() - 1);
  1006. }
  1007. }, menuPath);
  1008. }
  1009. private void createEditorMenu() {
  1010. addMenuCommand("Enabled", new ScheduledCommand() {
  1011. @Override
  1012. public void execute() {
  1013. grid.setEditorEnabled(!grid.isEditorEnabled());
  1014. }
  1015. }, "Component", "Editor");
  1016. addMenuCommand("Edit row 5", new ScheduledCommand() {
  1017. @Override
  1018. public void execute() {
  1019. grid.editRow(5);
  1020. }
  1021. }, "Component", "Editor");
  1022. addMenuCommand("Edit row 100", new ScheduledCommand() {
  1023. @Override
  1024. public void execute() {
  1025. grid.editRow(100);
  1026. }
  1027. }, "Component", "Editor");
  1028. addMenuCommand("Save", new ScheduledCommand() {
  1029. @Override
  1030. public void execute() {
  1031. grid.saveEditor();
  1032. }
  1033. }, "Component", "Editor");
  1034. addMenuCommand("Cancel edit", new ScheduledCommand() {
  1035. @Override
  1036. public void execute() {
  1037. grid.cancelEditor();
  1038. }
  1039. }, "Component", "Editor");
  1040. addMenuCommand("Change Save Caption", new ScheduledCommand() {
  1041. @Override
  1042. public void execute() {
  1043. grid.setEditorSaveCaption("ǝʌɐS");
  1044. }
  1045. }, "Component", "Editor");
  1046. addMenuCommand("Change Cancel Caption", new ScheduledCommand() {
  1047. @Override
  1048. public void execute() {
  1049. grid.setEditorCancelCaption("ʃǝɔuɐↃ");
  1050. }
  1051. }, "Component", "Editor");
  1052. addMenuCommand("Toggle second editor error", new ScheduledCommand() {
  1053. @Override
  1054. public void execute() {
  1055. secondEditorError = !secondEditorError;
  1056. }
  1057. }, "Component", "Editor");
  1058. }
  1059. private void configureFooterRow(final FooterRow row) {
  1060. setFooterTexts(row);
  1061. String rowTitle = "Row " + grid.getFooterRowCount();
  1062. final String[] menuPath = { "Component", "Footer", rowTitle };
  1063. addMenuCommand("Join column cells 0, 1", new ScheduledCommand() {
  1064. @Override
  1065. public void execute() {
  1066. row.join(row.getCell(grid.getColumn(0)),
  1067. row.getCell(grid.getColumn(1)))
  1068. .setText("Join column cells 0, 1");
  1069. }
  1070. }, menuPath);
  1071. addMenuCommand("Join columns 1, 2", new ScheduledCommand() {
  1072. @Override
  1073. public void execute() {
  1074. row.join(grid.getColumn(1), grid.getColumn(2))
  1075. .setText("Join columns 1, 2");
  1076. ;
  1077. }
  1078. }, menuPath);
  1079. addMenuCommand("Join all columns", new ScheduledCommand() {
  1080. @Override
  1081. public void execute() {
  1082. row.join(grid.getColumns()
  1083. .toArray(new Grid.Column[grid.getColumnCount()]))
  1084. .setText("Join all columns");
  1085. ;
  1086. }
  1087. }, menuPath);
  1088. }
  1089. private void createDataSourceMenu() {
  1090. final String[] menuPath = { "Component", "DataSource" };
  1091. addMenuCommand("Reset with 100 rows of Data", new ScheduledCommand() {
  1092. @Override
  1093. public void execute() {
  1094. ds.asList().clear();
  1095. data = createData(100);
  1096. ds.asList().addAll(data);
  1097. }
  1098. }, menuPath);
  1099. addMenuCommand("Reset with " + ROWS + " rows of Data",
  1100. new ScheduledCommand() {
  1101. @Override
  1102. public void execute() {
  1103. ds.asList().clear();
  1104. data = createData(ROWS);
  1105. ds.asList().addAll(data);
  1106. }
  1107. }, menuPath);
  1108. }
  1109. /**
  1110. * Creates a renderer for a {@link Renderers}
  1111. */
  1112. @SuppressWarnings("rawtypes")
  1113. private final Renderer createRenderer(Renderers renderer) {
  1114. switch (renderer) {
  1115. case TEXT_RENDERER:
  1116. return new TextRenderer();
  1117. case HTML_RENDERER:
  1118. return new HtmlRenderer() {
  1119. @Override
  1120. public void render(RendererCellReference cell,
  1121. String htmlString) {
  1122. super.render(cell, "<b>" + htmlString + "</b>");
  1123. }
  1124. };
  1125. case NUMBER_RENDERER:
  1126. return new NumberRenderer();
  1127. case DATE_RENDERER:
  1128. return new DateRenderer();
  1129. default:
  1130. return new TextRenderer();
  1131. }
  1132. }
  1133. /**
  1134. * Creates a collection of handlers for all the grid key events
  1135. */
  1136. private void createKeyHandlers() {
  1137. final List<VLabel> labels = new ArrayList<>();
  1138. for (int i = 0; i < 9; ++i) {
  1139. VLabel tmp = new VLabel();
  1140. addNorth(tmp, 20);
  1141. labels.add(tmp);
  1142. }
  1143. // Key Down Events
  1144. grid.addBodyKeyDownHandler(new BodyKeyDownHandler() {
  1145. private final VLabel label = labels.get(0);
  1146. @Override
  1147. public void onKeyDown(GridKeyDownEvent event) {
  1148. CellReference<?> focused = event.getFocusedCell();
  1149. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1150. focused.getColumnIndex());
  1151. }
  1152. });
  1153. grid.addHeaderKeyDownHandler(new HeaderKeyDownHandler() {
  1154. private final VLabel label = labels.get(1);
  1155. @Override
  1156. public void onKeyDown(GridKeyDownEvent event) {
  1157. CellReference<?> focused = event.getFocusedCell();
  1158. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1159. focused.getColumnIndex());
  1160. }
  1161. });
  1162. grid.addFooterKeyDownHandler(new FooterKeyDownHandler() {
  1163. private final VLabel label = labels.get(2);
  1164. @Override
  1165. public void onKeyDown(GridKeyDownEvent event) {
  1166. CellReference<?> focused = event.getFocusedCell();
  1167. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1168. focused.getColumnIndex());
  1169. }
  1170. });
  1171. // Key Up Events
  1172. grid.addBodyKeyUpHandler(new BodyKeyUpHandler() {
  1173. private final VLabel label = labels.get(3);
  1174. @Override
  1175. public void onKeyUp(GridKeyUpEvent event) {
  1176. CellReference<?> focused = event.getFocusedCell();
  1177. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1178. focused.getColumnIndex());
  1179. }
  1180. });
  1181. grid.addHeaderKeyUpHandler(new HeaderKeyUpHandler() {
  1182. private final VLabel label = labels.get(4);
  1183. @Override
  1184. public void onKeyUp(GridKeyUpEvent event) {
  1185. CellReference<?> focused = event.getFocusedCell();
  1186. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1187. focused.getColumnIndex());
  1188. }
  1189. });
  1190. grid.addFooterKeyUpHandler(new FooterKeyUpHandler() {
  1191. private final VLabel label = labels.get(5);
  1192. @Override
  1193. public void onKeyUp(GridKeyUpEvent event) {
  1194. CellReference<?> focused = event.getFocusedCell();
  1195. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1196. focused.getColumnIndex());
  1197. }
  1198. });
  1199. // Key Press Events
  1200. grid.addBodyKeyPressHandler(new BodyKeyPressHandler() {
  1201. private final VLabel label = labels.get(6);
  1202. @Override
  1203. public void onKeyPress(GridKeyPressEvent event) {
  1204. CellReference<?> focused = event.getFocusedCell();
  1205. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1206. focused.getColumnIndex());
  1207. }
  1208. });
  1209. grid.addHeaderKeyPressHandler(new HeaderKeyPressHandler() {
  1210. private final VLabel label = labels.get(7);
  1211. @Override
  1212. public void onKeyPress(GridKeyPressEvent event) {
  1213. CellReference<?> focused = event.getFocusedCell();
  1214. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1215. focused.getColumnIndex());
  1216. }
  1217. });
  1218. grid.addFooterKeyPressHandler(new FooterKeyPressHandler() {
  1219. private final VLabel label = labels.get(8);
  1220. @Override
  1221. public void onKeyPress(GridKeyPressEvent event) {
  1222. CellReference<?> focused = event.getFocusedCell();
  1223. updateLabel(label, event.toDebugString(), focused.getRowIndex(),
  1224. focused.getColumnIndex());
  1225. }
  1226. });
  1227. }
  1228. private void updateLabel(VLabel label, String output, int object,
  1229. int column) {
  1230. String coords = "(" + object + ", " + column + ")";
  1231. label.setText(coords + " " + output);
  1232. }
  1233. private void createDetailsMenu() {
  1234. String[] menupath = { "Component", "Row details" };
  1235. addMenuCommand("Set generator", new ScheduledCommand() {
  1236. @Override
  1237. public void execute() {
  1238. grid.setDetailsGenerator(new DetailsGenerator() {
  1239. @Override
  1240. public Widget getDetails(int rowIndex) {
  1241. FlowPanel panel = new FlowPanel();
  1242. final Label label = new Label("Row: " + rowIndex + ".");
  1243. Button button = new Button("Button",
  1244. (ClickHandler) event -> label
  1245. .setText("clicked"));
  1246. panel.add(label);
  1247. panel.add(button);
  1248. return panel;
  1249. }
  1250. });
  1251. }
  1252. }, menupath);
  1253. addMenuCommand("Set faulty generator", new ScheduledCommand() {
  1254. @Override
  1255. public void execute() {
  1256. grid.setDetailsGenerator(new DetailsGenerator() {
  1257. @Override
  1258. public Widget getDetails(int rowIndex) {
  1259. throw new RuntimeException("This is by design.");
  1260. }
  1261. });
  1262. }
  1263. }, menupath);
  1264. addMenuCommand("Set empty generator", new ScheduledCommand() {
  1265. @Override
  1266. public void execute() {
  1267. grid.setDetailsGenerator(new DetailsGenerator() {
  1268. /*
  1269. * While this is functionally equivalent to the NULL
  1270. * generator, it's good to be explicit, since the behavior
  1271. * isn't strictly tied between them. NULL generator might be
  1272. * changed to render something different by default, and an
  1273. * empty generator might behave differently also in the
  1274. * future.
  1275. */
  1276. @Override
  1277. public Widget getDetails(int rowIndex) {
  1278. return null;
  1279. }
  1280. });
  1281. }
  1282. }, menupath);
  1283. String[] togglemenupath = { menupath[0], menupath[1],
  1284. "Toggle details for..." };
  1285. for (int i : new int[] { 0, 1, 100, 200, 300, 400, 500, 600, 700, 800,
  1286. 900, 999 }) {
  1287. final int rowIndex = i;
  1288. addMenuCommand("Row " + rowIndex, new ScheduledCommand() {
  1289. boolean visible = false;
  1290. @Override
  1291. public void execute() {
  1292. visible = !visible;
  1293. grid.setDetailsVisible(rowIndex, visible);
  1294. }
  1295. }, togglemenupath);
  1296. }
  1297. }
  1298. private static Logger getLogger() {
  1299. return Logger.getLogger(GridBasicClientFeaturesWidget.class.getName());
  1300. }
  1301. private void createSidebarMenu() {
  1302. String[] menupath = { "Component", "Sidebar" };
  1303. final List<MenuItem> customMenuItems = new ArrayList<>();
  1304. final List<MenuItemSeparator> separators = new ArrayList<>();
  1305. addMenuCommand("Add item to end", new ScheduledCommand() {
  1306. @Override
  1307. public void execute() {
  1308. MenuItem item = createSidebarMenuItem(customMenuItems.size());
  1309. customMenuItems.add(item);
  1310. grid.getSidebarMenu().addItem(item);
  1311. }
  1312. }, menupath);
  1313. addMenuCommand("Add item before index 1", new ScheduledCommand() {
  1314. @Override
  1315. public void execute() {
  1316. MenuItem item = createSidebarMenuItem(customMenuItems.size());
  1317. customMenuItems.add(item);
  1318. grid.getSidebarMenu().insertItem(item, 1);
  1319. }
  1320. }, menupath);
  1321. addMenuCommand("Remove last added item", new ScheduledCommand() {
  1322. @Override
  1323. public void execute() {
  1324. grid.getSidebarMenu().removeItem(
  1325. customMenuItems.remove(customMenuItems.size() - 1));
  1326. }
  1327. }, menupath);
  1328. addMenuCommand("Add separator to end", new ScheduledCommand() {
  1329. @Override
  1330. public void execute() {
  1331. MenuItemSeparator separator = new MenuItemSeparator();
  1332. separators.add(separator);
  1333. grid.getSidebarMenu().addSeparator(separator);
  1334. }
  1335. }, menupath);
  1336. addMenuCommand("Add separator before index 1", new ScheduledCommand() {
  1337. @Override
  1338. public void execute() {
  1339. MenuItemSeparator separator = new MenuItemSeparator();
  1340. separators.add(separator);
  1341. grid.getSidebarMenu().insertSeparator(separator, 1);
  1342. }
  1343. }, menupath);
  1344. addMenuCommand("Remove last added separator", new ScheduledCommand() {
  1345. @Override
  1346. public void execute() {
  1347. grid.getSidebarMenu().removeSeparator(
  1348. separators.remove(separators.size() - 1));
  1349. }
  1350. }, menupath);
  1351. addMenuCommand("Toggle sidebar visibility", new ScheduledCommand() {
  1352. @Override
  1353. public void execute() {
  1354. grid.setSidebarOpen(!grid.isSidebarOpen());
  1355. }
  1356. }, menupath);
  1357. addMenuCommand("Open sidebar and disable grid", new ScheduledCommand() {
  1358. @Override
  1359. public void execute() {
  1360. grid.setSidebarOpen(true);
  1361. Scheduler.get()
  1362. .scheduleFixedDelay(new Scheduler.RepeatingCommand() {
  1363. @Override
  1364. public boolean execute() {
  1365. if (grid.isSidebarOpen()) {
  1366. grid.setEnabled(false);
  1367. return false;
  1368. }
  1369. return true;
  1370. }
  1371. }, 250);
  1372. }
  1373. }, menupath);
  1374. }
  1375. private MenuItem createSidebarMenuItem(final int index) {
  1376. final MenuItem menuItem = new MenuItem("Custom menu item " + index,
  1377. new ScheduledCommand() {
  1378. @Override
  1379. public void execute() {
  1380. if (index % 2 == 0) {
  1381. grid.setSidebarOpen(false);
  1382. }
  1383. getLogger().info("Menu item " + index + " selected");
  1384. }
  1385. });
  1386. return menuItem;
  1387. }
  1388. }