Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

VTablePaging.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.Iterator;
  8. import java.util.Set;
  9. import com.google.gwt.user.client.DOM;
  10. import com.google.gwt.user.client.Event;
  11. import com.google.gwt.user.client.Window;
  12. import com.google.gwt.user.client.ui.Button;
  13. import com.google.gwt.user.client.ui.ClickListener;
  14. import com.google.gwt.user.client.ui.Composite;
  15. import com.google.gwt.user.client.ui.Grid;
  16. import com.google.gwt.user.client.ui.HTML;
  17. import com.google.gwt.user.client.ui.HorizontalPanel;
  18. import com.google.gwt.user.client.ui.Label;
  19. import com.google.gwt.user.client.ui.SimplePanel;
  20. import com.google.gwt.user.client.ui.VerticalPanel;
  21. import com.google.gwt.user.client.ui.Widget;
  22. import com.vaadin.terminal.gwt.client.ApplicationConnection;
  23. import com.vaadin.terminal.gwt.client.Paintable;
  24. import com.vaadin.terminal.gwt.client.UIDL;
  25. /**
  26. * TODO make this work (just an early prototype). We may want to have paging
  27. * style table which will be much lighter than VScrollTable is.
  28. */
  29. public class VTablePaging extends Composite implements Table, Paintable,
  30. ClickListener {
  31. private final Grid tBody = new Grid();
  32. private final Button nextPage = new Button(">");
  33. private final Button prevPage = new Button("<");
  34. private final Button firstPage = new Button("<<");
  35. private final Button lastPage = new Button(">>");
  36. private int pageLength = 15;
  37. private boolean rowHeaders = false;
  38. private ApplicationConnection client;
  39. private String id;
  40. private boolean immediate = false;
  41. private int selectMode = Table.SELECT_MODE_NONE;
  42. private final ArrayList selectedRowKeys = new ArrayList();
  43. private int totalRows;
  44. private final HashMap visibleColumns = new HashMap();
  45. private int rows;
  46. private int firstRow;
  47. private boolean sortAscending = true;
  48. private final HorizontalPanel pager;
  49. public HashMap rowKeysToTableRows = new HashMap();
  50. public VTablePaging() {
  51. tBody.setStyleName("itable-tbody");
  52. final VerticalPanel panel = new VerticalPanel();
  53. pager = new HorizontalPanel();
  54. pager.add(firstPage);
  55. firstPage.addClickListener(this);
  56. pager.add(prevPage);
  57. prevPage.addClickListener(this);
  58. pager.add(nextPage);
  59. nextPage.addClickListener(this);
  60. pager.add(lastPage);
  61. lastPage.addClickListener(this);
  62. panel.add(pager);
  63. panel.add(tBody);
  64. initWidget(panel);
  65. }
  66. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  67. if (client.updateComponent(this, uidl, true)) {
  68. return;
  69. }
  70. this.client = client;
  71. id = uidl.getStringAttribute("id");
  72. immediate = uidl.getBooleanAttribute("immediate");
  73. totalRows = uidl.getIntAttribute("totalrows");
  74. pageLength = uidl.getIntAttribute("pagelength");
  75. firstRow = uidl.getIntAttribute("firstrow");
  76. rows = uidl.getIntAttribute("rows");
  77. if (uidl.hasAttribute("selectmode")) {
  78. if (uidl.getStringAttribute("selectmode").equals("multi")) {
  79. selectMode = Table.SELECT_MODE_MULTI;
  80. } else {
  81. selectMode = Table.SELECT_MODE_SINGLE;
  82. }
  83. if (uidl.hasAttribute("selected")) {
  84. final Set selectedKeys = uidl
  85. .getStringArrayVariableAsSet("selected");
  86. selectedRowKeys.clear();
  87. for (final Iterator it = selectedKeys.iterator(); it.hasNext();) {
  88. selectedRowKeys.add(it.next());
  89. }
  90. }
  91. }
  92. if (uidl.hasVariable("sortascending")) {
  93. sortAscending = uidl.getBooleanVariable("sortascending");
  94. }
  95. if (uidl.hasAttribute("rowheaders")) {
  96. rowHeaders = true;
  97. }
  98. UIDL rowData = null;
  99. UIDL visibleColumns = null;
  100. for (final Iterator it = uidl.getChildIterator(); it.hasNext();) {
  101. final UIDL c = (UIDL) it.next();
  102. if (c.getTag().equals("rows")) {
  103. rowData = c;
  104. } else if (c.getTag().equals("actions")) {
  105. updateActionMap(c);
  106. } else if (c.getTag().equals("visiblecolumns")) {
  107. visibleColumns = c;
  108. }
  109. }
  110. tBody.resize(rows + 1, uidl.getIntAttribute("cols")
  111. + (rowHeaders ? 1 : 0));
  112. updateHeader(visibleColumns);
  113. updateBody(rowData);
  114. updatePager();
  115. }
  116. private void updateHeader(UIDL c) {
  117. final Iterator it = c.getChildIterator();
  118. visibleColumns.clear();
  119. int colIndex = (rowHeaders ? 1 : 0);
  120. while (it.hasNext()) {
  121. final UIDL col = (UIDL) it.next();
  122. final String cid = col.getStringAttribute("cid");
  123. if (!col.hasAttribute("collapsed")) {
  124. tBody.setWidget(0, colIndex, new HeaderCell(cid, col
  125. .getStringAttribute("caption")));
  126. }
  127. colIndex++;
  128. }
  129. }
  130. private void updateActionMap(UIDL c) {
  131. // TODO Auto-generated method stub
  132. }
  133. /**
  134. * Updates row data from uidl. UpdateFromUIDL delegates updating tBody to
  135. * this method.
  136. *
  137. * Updates may be to different part of tBody, depending on update type. It
  138. * can be initial row data, scroll up, scroll down...
  139. *
  140. * @param uidl
  141. * which contains row data
  142. */
  143. private void updateBody(UIDL uidl) {
  144. final Iterator it = uidl.getChildIterator();
  145. int curRowIndex = 1;
  146. while (it.hasNext()) {
  147. final UIDL rowUidl = (UIDL) it.next();
  148. final TableRow row = new TableRow(curRowIndex, String
  149. .valueOf(rowUidl.getIntAttribute("key")), rowUidl
  150. .hasAttribute("selected"));
  151. int colIndex = 0;
  152. if (rowHeaders) {
  153. tBody.setWidget(curRowIndex, colIndex, new BodyCell(row,
  154. rowUidl.getStringAttribute("caption")));
  155. colIndex++;
  156. }
  157. final Iterator cells = rowUidl.getChildIterator();
  158. while (cells.hasNext()) {
  159. final Object cell = cells.next();
  160. if (cell instanceof String) {
  161. tBody.setWidget(curRowIndex, colIndex, new BodyCell(row,
  162. (String) cell));
  163. } else {
  164. final Paintable cellContent = client
  165. .getPaintable((UIDL) cell);
  166. final BodyCell bodyCell = new BodyCell(row);
  167. bodyCell.setWidget((Widget) cellContent);
  168. tBody.setWidget(curRowIndex, colIndex, bodyCell);
  169. }
  170. colIndex++;
  171. }
  172. curRowIndex++;
  173. }
  174. }
  175. private void updatePager() {
  176. if (pageLength == 0) {
  177. pager.setVisible(false);
  178. return;
  179. }
  180. if (isFirstPage()) {
  181. firstPage.setEnabled(false);
  182. prevPage.setEnabled(false);
  183. } else {
  184. firstPage.setEnabled(true);
  185. prevPage.setEnabled(true);
  186. }
  187. if (hasNextPage()) {
  188. nextPage.setEnabled(true);
  189. lastPage.setEnabled(true);
  190. } else {
  191. nextPage.setEnabled(false);
  192. lastPage.setEnabled(false);
  193. }
  194. }
  195. private boolean hasNextPage() {
  196. if (firstRow + rows + 1 > totalRows) {
  197. return false;
  198. }
  199. return true;
  200. }
  201. private boolean isFirstPage() {
  202. if (firstRow == 0) {
  203. return true;
  204. }
  205. return false;
  206. }
  207. public void onClick(Widget sender) {
  208. if (sender instanceof Button) {
  209. if (sender == firstPage) {
  210. client.updateVariable(id, "firstvisible", 0, true);
  211. } else if (sender == nextPage) {
  212. client.updateVariable(id, "firstvisible",
  213. firstRow + pageLength, true);
  214. } else if (sender == prevPage) {
  215. int newFirst = firstRow - pageLength;
  216. if (newFirst < 0) {
  217. newFirst = 0;
  218. }
  219. client.updateVariable(id, "firstvisible", newFirst, true);
  220. } else if (sender == lastPage) {
  221. client.updateVariable(id, "firstvisible", totalRows
  222. - pageLength, true);
  223. }
  224. }
  225. if (sender instanceof HeaderCell) {
  226. final HeaderCell hCell = (HeaderCell) sender;
  227. client.updateVariable(id, "sortcolumn", hCell.getCid(), false);
  228. client.updateVariable(id, "sortascending", (sortAscending ? false
  229. : true), true);
  230. }
  231. }
  232. private class HeaderCell extends HTML {
  233. private String cid;
  234. public String getCid() {
  235. return cid;
  236. }
  237. public void setCid(String pid) {
  238. cid = pid;
  239. }
  240. HeaderCell(String pid, String caption) {
  241. super();
  242. cid = pid;
  243. addClickListener(VTablePaging.this);
  244. setText(caption);
  245. // TODO remove debug color
  246. DOM.setStyleAttribute(getElement(), "color", "brown");
  247. DOM.setStyleAttribute(getElement(), "font-weight", "bold");
  248. }
  249. }
  250. /**
  251. * Abstraction of table cell content. In needs to know on which row it is in
  252. * case of context click.
  253. *
  254. * @author mattitahvonen
  255. */
  256. public class BodyCell extends SimplePanel {
  257. private final TableRow row;
  258. public BodyCell(TableRow row) {
  259. super();
  260. sinkEvents(Event.BUTTON_LEFT | Event.BUTTON_RIGHT);
  261. this.row = row;
  262. }
  263. public BodyCell(TableRow row2, String textContent) {
  264. super();
  265. sinkEvents(Event.BUTTON_LEFT | Event.BUTTON_RIGHT);
  266. row = row2;
  267. setWidget(new Label(textContent));
  268. }
  269. @Override
  270. public void onBrowserEvent(Event event) {
  271. System.out.println("CEll event: " + event.toString());
  272. switch (DOM.eventGetType(event)) {
  273. case Event.BUTTON_RIGHT:
  274. row.showContextMenu(event);
  275. Window.alert("context menu un-implemented");
  276. DOM.eventCancelBubble(event, true);
  277. break;
  278. case Event.BUTTON_LEFT:
  279. if (selectMode > Table.SELECT_MODE_NONE) {
  280. row.toggleSelected();
  281. }
  282. break;
  283. default:
  284. break;
  285. }
  286. super.onBrowserEvent(event);
  287. }
  288. }
  289. private class TableRow {
  290. private final String key;
  291. private final int rowIndex;
  292. private boolean selected = false;
  293. public TableRow(int rowIndex, String rowKey, boolean selected) {
  294. rowKeysToTableRows.put(rowKey, this);
  295. this.rowIndex = rowIndex;
  296. key = rowKey;
  297. setSelected(selected);
  298. }
  299. /**
  300. * This method is used to set row status. Does not change value on
  301. * server.
  302. *
  303. * @param selected
  304. */
  305. public void setSelected(boolean sel) {
  306. selected = sel;
  307. if (selected) {
  308. selectedRowKeys.add(key);
  309. DOM.setStyleAttribute(tBody.getRowFormatter().getElement(
  310. rowIndex), "background", "yellow");
  311. } else {
  312. selectedRowKeys.remove(key);
  313. DOM.setStyleAttribute(tBody.getRowFormatter().getElement(
  314. rowIndex), "background", "transparent");
  315. }
  316. }
  317. public void setContextMenuOptions(HashMap options) {
  318. }
  319. /**
  320. * Toggles rows select state. Also updates state to server according to
  321. * tables immediate flag.
  322. *
  323. */
  324. public void toggleSelected() {
  325. if (selected) {
  326. setSelected(false);
  327. } else {
  328. if (selectMode == Table.SELECT_MODE_SINGLE) {
  329. deselectAll();
  330. }
  331. setSelected(true);
  332. }
  333. client.updateVariable(id, "selected", selectedRowKeys.toArray(),
  334. immediate);
  335. }
  336. /**
  337. * Shows context menu for this row.
  338. *
  339. * @param event
  340. * Event which triggered context menu. Correct place for
  341. * context menu can be determined with it.
  342. */
  343. public void showContextMenu(Event event) {
  344. System.out.println("TODO: Show context menu");
  345. }
  346. }
  347. public void deselectAll() {
  348. final Object[] keys = selectedRowKeys.toArray();
  349. for (int i = 0; i < keys.length; i++) {
  350. final TableRow tableRow = (TableRow) rowKeysToTableRows
  351. .get(keys[i]);
  352. if (tableRow != null) {
  353. tableRow.setSelected(false);
  354. }
  355. }
  356. // still ensure all selects are removed from
  357. selectedRowKeys.clear();
  358. }
  359. public void add(Widget w) {
  360. // TODO Auto-generated method stub
  361. }
  362. public void clear() {
  363. // TODO Auto-generated method stub
  364. }
  365. public Iterator iterator() {
  366. // TODO Auto-generated method stub
  367. return null;
  368. }
  369. public boolean remove(Widget w) {
  370. // TODO Auto-generated method stub
  371. return false;
  372. }
  373. }