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 59KB

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