PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/core/org.jowidgets.impl/src/main/java/org/jowidgets/impl/model/table/SimpleTableModel.java

http://jo-widgets.googlecode.com/
Java | 575 lines | 461 code | 71 blank | 43 comment | 82 complexity | c9916eb2a44a6b12471e3158fd850b6e MD5 | raw file
  1. /*
  2. * Copyright (c) 2011, grossmann
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the jo-widgets.org nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  26. * DAMAGE.
  27. */
  28. package org.jowidgets.impl.model.table;
  29. import java.util.ArrayList;
  30. import java.util.Arrays;
  31. import java.util.Collection;
  32. import java.util.Collections;
  33. import java.util.List;
  34. import org.jowidgets.api.model.table.IDefaultTableColumn;
  35. import org.jowidgets.api.model.table.ISimpleTableModel;
  36. import org.jowidgets.api.model.table.ITableCellBuilder;
  37. import org.jowidgets.common.color.IColorConstant;
  38. import org.jowidgets.common.image.IImageConstant;
  39. import org.jowidgets.common.model.ITableCell;
  40. import org.jowidgets.common.model.ITableDataModelListener;
  41. import org.jowidgets.common.model.ITableDataModelObservable;
  42. import org.jowidgets.tools.controller.TableDataModelObservable;
  43. import org.jowidgets.util.Assert;
  44. class SimpleTableModel extends DefaultTableColumnModel implements ISimpleTableModel, ITableDataModelObservable {
  45. private final TableDataModelObservable dataModelObservable;
  46. private final ArrayList<ArrayList<ITableCell>> data;
  47. private final IColorConstant evenBackgroundColor;
  48. private final IColorConstant oddBackgroundColor;
  49. private final boolean cellsEditableDefault;
  50. private ArrayList<Integer> selection;
  51. private boolean fireDataChanged;
  52. private boolean fireSelectionChanged;
  53. SimpleTableModel(
  54. final int rowCount,
  55. final int columnCount,
  56. final boolean cellsEditableDefault,
  57. final IColorConstant evenBackgroundColor,
  58. final IColorConstant oddBackgroundColor) {
  59. super(columnCount);
  60. this.dataModelObservable = new TableDataModelObservable();
  61. this.cellsEditableDefault = cellsEditableDefault;
  62. this.evenBackgroundColor = evenBackgroundColor;
  63. this.oddBackgroundColor = oddBackgroundColor;
  64. this.selection = new ArrayList<Integer>();
  65. this.data = new ArrayList<ArrayList<ITableCell>>();
  66. final ITableCellBuilder cellBuilder = cellBuilder();
  67. for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
  68. final ArrayList<ITableCell> row = new ArrayList<ITableCell>();
  69. data.add(row);
  70. for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
  71. row.add(cellBuilder.build());
  72. }
  73. }
  74. this.fireDataChanged = false;
  75. this.fireSelectionChanged = false;
  76. }
  77. @Override
  78. public void modifyModelStart() {
  79. super.modifyModelStart();
  80. }
  81. @Override
  82. public void modifyModelEnd() {
  83. super.modifyModelEnd();
  84. if (fireDataChanged && isFireEvents()) {
  85. dataModelObservable.fireDataChanged();
  86. }
  87. if (fireSelectionChanged && isFireEvents()) {
  88. dataModelObservable.fireSelectionChanged();
  89. }
  90. fireDataChanged = false;
  91. fireSelectionChanged = false;
  92. }
  93. @Override
  94. public int getRowCount() {
  95. return data.size();
  96. }
  97. @Override
  98. public ITableCell getCell(final int rowIndex, final int columnIndex) {
  99. final TableCell result = new TableCell(data.get(rowIndex).get(columnIndex));
  100. if (result.getBackgroundColor() == null) {
  101. if (rowIndex % 2 == 0) {
  102. result.setBackgroundColor(evenBackgroundColor);
  103. }
  104. else {
  105. result.setBackgroundColor(oddBackgroundColor);
  106. }
  107. }
  108. return result;
  109. }
  110. @Override
  111. public int getFirstSelectedRow() {
  112. final ArrayList<Integer> currentSelection = getSelection();
  113. if (currentSelection.size() > 0) {
  114. return Collections.min(currentSelection).intValue();
  115. }
  116. return -1;
  117. }
  118. @Override
  119. public int getLastSelectedRow() {
  120. final ArrayList<Integer> currentSelection = getSelection();
  121. if (currentSelection.size() > 0) {
  122. return Collections.max(currentSelection).intValue();
  123. }
  124. return -1;
  125. }
  126. @Override
  127. public ArrayList<ITableCell> getRow(final int rowIndex) {
  128. final ArrayList<ITableCell> result = new ArrayList<ITableCell>();
  129. for (int columnIndex = 0; columnIndex < getColumnCount(); columnIndex++) {
  130. result.add(data.get(rowIndex).get(columnIndex));
  131. }
  132. return result;
  133. }
  134. @Override
  135. public ArrayList<String> getRowTexts(final int rowIndex) {
  136. final ArrayList<String> result = new ArrayList<String>();
  137. for (int columnIndex = 0; columnIndex < getColumnCount(); columnIndex++) {
  138. result.add(data.get(rowIndex).get(columnIndex).getText());
  139. }
  140. return result;
  141. }
  142. @Override
  143. public void setCell(final int rowIndex, final int columnIndex, final ITableCell cell) {
  144. Assert.paramNotNull(cell, "cell");
  145. data.get(rowIndex).set(columnIndex, cell);
  146. if (isEventsFreezed()) {
  147. fireDataChanged = true;
  148. }
  149. else if (isFireEvents()) {
  150. dataModelObservable.fireRowsChanged(new int[] {rowIndex});
  151. }
  152. }
  153. @Override
  154. public void setRow(final int rowIndex, final ITableCell... cells) {
  155. Assert.paramNotNull(cells, "cells");
  156. for (int i = 0; i < cells.length; i++) {
  157. data.get(rowIndex).set(i, cells[i]);
  158. }
  159. if (isEventsFreezed()) {
  160. fireDataChanged = true;
  161. }
  162. else if (isFireEvents()) {
  163. dataModelObservable.fireRowsChanged(new int[] {rowIndex});
  164. }
  165. }
  166. @Override
  167. public void addRows(final int startRowIndex, final int rowCount) {
  168. final int[] rowIndices = new int[rowCount];
  169. final ITableCellBuilder cellBuilder = cellBuilder();
  170. final int columnCount = getColumnCount();
  171. for (int i = 0; i < rowCount; i++) {
  172. rowIndices[i] = startRowIndex + i;
  173. final ArrayList<ITableCell> row = new ArrayList<ITableCell>();
  174. data.add(startRowIndex, row);
  175. for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
  176. row.add(cellBuilder.build());
  177. }
  178. }
  179. if (isEventsFreezed()) {
  180. fireDataChanged = true;
  181. }
  182. else if (isFireEvents()) {
  183. dataModelObservable.fireRowsAdded(rowIndices);
  184. }
  185. }
  186. @Override
  187. public void addRow(final int rowIndex, final ITableCell... cells) {
  188. Assert.paramNotNull(cells, "cells");
  189. final ITableCellBuilder cellBuilder = cellBuilder();
  190. final int columnCount = getColumnCount();
  191. final ArrayList<ITableCell> row = new ArrayList<ITableCell>();
  192. data.add(rowIndex, row);
  193. for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
  194. if (columnIndex < cells.length) {
  195. row.add(cells[columnIndex]);
  196. }
  197. else {
  198. row.add(cellBuilder.build());
  199. }
  200. }
  201. if (isEventsFreezed()) {
  202. fireDataChanged = true;
  203. }
  204. else if (isFireEvents()) {
  205. dataModelObservable.fireRowsAdded(new int[] {rowIndex});
  206. }
  207. }
  208. @Override
  209. public void removeRow(final int index) {
  210. data.remove(index);
  211. final boolean selectionChanged = selection.remove(Integer.valueOf(index));
  212. if (isEventsFreezed()) {
  213. fireDataChanged = true;
  214. }
  215. else if (isFireEvents()) {
  216. dataModelObservable.fireRowsRemoved(new int[] {index});
  217. }
  218. if (selectionChanged) {
  219. if (isEventsFreezed()) {
  220. fireSelectionChanged = true;
  221. }
  222. else if (isFireEvents()) {
  223. dataModelObservable.fireSelectionChanged();
  224. }
  225. }
  226. }
  227. @Override
  228. public void removeRows(final int fromIndex, final int toIndex) {
  229. if (fromIndex > toIndex) {
  230. throw new IllegalArgumentException("From index must be less or equal than to index.");
  231. }
  232. final int[] indices = new int[1 + toIndex - fromIndex];
  233. boolean selectionChanged = false;
  234. for (int i = 0; i < indices.length; i++) {
  235. indices[i] = fromIndex + i;
  236. data.remove(fromIndex);
  237. selectionChanged = selectionChanged || selection.remove(Integer.valueOf(fromIndex + i));
  238. }
  239. if (isEventsFreezed()) {
  240. fireDataChanged = true;
  241. }
  242. else if (isFireEvents()) {
  243. dataModelObservable.fireRowsRemoved(indices);
  244. }
  245. if (selectionChanged) {
  246. if (isEventsFreezed()) {
  247. fireSelectionChanged = true;
  248. }
  249. else if (isFireEvents()) {
  250. dataModelObservable.fireSelectionChanged();
  251. }
  252. }
  253. }
  254. @Override
  255. public void removeRows(final int... rows) {
  256. Assert.paramNotNull(rows, "rows");
  257. //If rows is sorted, for each already removed row the
  258. //index must be reduced by one
  259. Arrays.sort(rows);
  260. int removedRowCount = 0;
  261. boolean selectionChanged = false;
  262. for (final int row : rows) {
  263. data.remove(row - removedRowCount);
  264. selectionChanged = selection.remove(Integer.valueOf(row)) || selectionChanged;
  265. removedRowCount++;
  266. }
  267. if (isEventsFreezed()) {
  268. fireDataChanged = true;
  269. }
  270. else if (isFireEvents()) {
  271. dataModelObservable.fireRowsRemoved(rows);
  272. }
  273. if (selectionChanged) {
  274. if (isEventsFreezed()) {
  275. fireSelectionChanged = true;
  276. }
  277. else if (isFireEvents()) {
  278. dataModelObservable.fireSelectionChanged();
  279. }
  280. }
  281. }
  282. @Override
  283. public void removeAllRows() {
  284. final boolean selectionChanged = selection.size() > 0;
  285. data.clear();
  286. if (isEventsFreezed()) {
  287. fireDataChanged = true;
  288. }
  289. else if (isFireEvents()) {
  290. dataModelObservable.fireDataChanged();
  291. }
  292. if (selectionChanged) {
  293. if (isEventsFreezed()) {
  294. fireSelectionChanged = true;
  295. }
  296. else if (isFireEvents()) {
  297. dataModelObservable.fireSelectionChanged();
  298. }
  299. }
  300. }
  301. @Override
  302. public ArrayList<Integer> getSelection() {
  303. return new ArrayList<Integer>(selection);
  304. }
  305. @Override
  306. public void setSelection(Collection<Integer> selection) {
  307. if (selection == null) {
  308. selection = new ArrayList<Integer>();
  309. }
  310. if (!this.selection.equals(selection)) {
  311. this.selection = new ArrayList<Integer>(selection);
  312. if (isFireEvents()) {
  313. dataModelObservable.fireSelectionChanged();
  314. }
  315. }
  316. }
  317. @Override
  318. public ITableDataModelObservable getTableDataModelObservable() {
  319. return this;
  320. }
  321. @Override
  322. public void addDataModelListener(final ITableDataModelListener listener) {
  323. dataModelObservable.addDataModelListener(listener);
  324. }
  325. @Override
  326. public void removeDataModelListener(final ITableDataModelListener listener) {
  327. dataModelObservable.removeDataModelListener(listener);
  328. }
  329. ////////////////////////////////////////////////////////////////////////////////////////////////
  330. //Overridden from column model start
  331. ////////////////////////////////////////////////////////////////////////////////////////////////
  332. @Override
  333. public void addColumn(final int columnIndex, final IDefaultTableColumn column) {
  334. if (data != null) {
  335. final ITableCellBuilder cellBuilder = cellBuilder();
  336. for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
  337. data.get(rowIndex).add(columnIndex, cellBuilder.build());
  338. }
  339. }
  340. super.addColumn(columnIndex, column);
  341. }
  342. @Override
  343. public void removeColumns(final int... columnIndices) {
  344. Assert.paramNotNull(columnIndices, "columnIndices");
  345. //If rows is sorted, for each already removed row the
  346. //index must be reduced by one
  347. Arrays.sort(columnIndices);
  348. for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
  349. int removedColumnCount = 0;
  350. for (final int columnIndex : columnIndices) {
  351. data.get(rowIndex).remove(columnIndex - removedColumnCount);
  352. removedColumnCount++;
  353. }
  354. }
  355. super.removeColumns(columnIndices);
  356. }
  357. ////////////////////////////////////////////////////////////////////////////////////////////////
  358. //Overridden from column model end
  359. ////////////////////////////////////////////////////////////////////////////////////////////////
  360. ////////////////////////////////////////////////////////////////////////////////////////////////
  361. //Convenience methods start
  362. ////////////////////////////////////////////////////////////////////////////////////////////////
  363. @Override
  364. public void addRow() {
  365. addRows(getRowCount(), 1);
  366. }
  367. @Override
  368. public void addRow(final int rowIndex) {
  369. addRows(rowIndex, 1);
  370. }
  371. @Override
  372. public void addRow(final ITableCell... cells) {
  373. addRow(getRowCount(), cells);
  374. }
  375. @Override
  376. public void addRow(final ITableCellBuilder... cellBuilders) {
  377. addRow(getRowCount(), cellBuilders);
  378. }
  379. @Override
  380. public void addRow(final int rowIndex, final ITableCellBuilder... cellBuilders) {
  381. Assert.paramNotNull(cellBuilders, "cellBuilders");
  382. final ITableCell[] cells = new ITableCell[cellBuilders.length];
  383. for (int i = 0; i < cellBuilders.length; i++) {
  384. cells[i] = cellBuilders[i].build();
  385. }
  386. addRow(rowIndex, cells);
  387. }
  388. @Override
  389. public void addRow(final String... cellTexts) {
  390. addRow(getRowCount(), cellTexts);
  391. }
  392. @Override
  393. public void addRow(final int rowIndex, final String... cellTexts) {
  394. Assert.paramNotNull(cellTexts, "cellTexts");
  395. final ITableCell[] cells = new ITableCell[cellTexts.length];
  396. for (int i = 0; i < cellTexts.length; i++) {
  397. cells[i] = cellBuilder().setText(cellTexts[i]).build();
  398. }
  399. addRow(rowIndex, cells);
  400. }
  401. @Override
  402. public void addRow(final List<String> cellTexts) {
  403. addRow(getRowCount(), cellTexts);
  404. }
  405. @Override
  406. public void addRow(final int rowIndex, final List<String> cellTexts) {
  407. Assert.paramNotNull(cellTexts, "cellTexts");
  408. final ITableCell[] cells = new ITableCell[cellTexts.size()];
  409. int i = 0;
  410. for (final String cellText : cellTexts) {
  411. cells[i] = cellBuilder().setText(cellText).build();
  412. i++;
  413. }
  414. addRow(rowIndex, cells);
  415. }
  416. @Override
  417. public void setCell(final int rowIndex, final int columnIndex, final ITableCellBuilder cellBuilder) {
  418. setCell(rowIndex, columnIndex, cellBuilder.build());
  419. }
  420. @Override
  421. public void setCell(final int rowIndex, final int columnIndex, final String text) {
  422. setCell(rowIndex, columnIndex, cellBuilder().setText(text));
  423. }
  424. @Override
  425. public void setCell(final int rowIndex, final int columnIndex, final String text, final IImageConstant icon) {
  426. setCell(rowIndex, columnIndex, cellBuilder().setText(text).setIcon(icon));
  427. }
  428. @Override
  429. public void setCell(final int rowIndex, final int columnIndex, final String text, final boolean editable) {
  430. setCell(rowIndex, columnIndex, cellBuilder().setText(text).setEditable(editable));
  431. }
  432. @Override
  433. public void setRow(final int rowIndex, final ITableCellBuilder... cellBuilders) {
  434. Assert.paramNotNull(cellBuilders, "cellBuilders");
  435. final ITableCell[] cells = new ITableCell[cellBuilders.length];
  436. for (int columnIndex = 0; columnIndex < getColumnCount(); columnIndex++) {
  437. cells[columnIndex] = cellBuilders[columnIndex].build();
  438. }
  439. }
  440. @Override
  441. public void setCellEditable(final int rowIndex, final int columnIndex, final boolean editable) {
  442. final TableCell cell = new TableCell(getCell(rowIndex, columnIndex));
  443. cell.setEditable(editable);
  444. setCell(rowIndex, columnIndex, cell);
  445. }
  446. @Override
  447. public void setCellText(final int rowIndex, final int columnIndex, final String text) {
  448. final TableCell cell = new TableCell(getCell(rowIndex, columnIndex));
  449. cell.setText(text);
  450. setCell(rowIndex, columnIndex, cell);
  451. }
  452. @Override
  453. public void setCellTooltipText(final int rowIndex, final int columnIndex, final String tooltipText) {
  454. final TableCell cell = new TableCell(getCell(rowIndex, columnIndex));
  455. cell.setToolTipText(tooltipText);
  456. setCell(rowIndex, columnIndex, cell);
  457. }
  458. @Override
  459. public void setCellIcon(final int rowIndex, final int columnIndex, final IImageConstant icon) {
  460. final TableCell cell = new TableCell(getCell(rowIndex, columnIndex));
  461. cell.setIcon(icon);
  462. setCell(rowIndex, columnIndex, cell);
  463. }
  464. @Override
  465. public void setRowTexts(final int rowIndex, final String... cellTexts) {
  466. Assert.paramNotNull(cellTexts, "cellTexts");
  467. final ITableCell[] cells = new ITableCell[cellTexts.length];
  468. for (int columnIndex = 0; columnIndex < getColumnCount(); columnIndex++) {
  469. final TableCell cell = new TableCell(getCell(rowIndex, columnIndex));
  470. cell.setText(cellTexts[columnIndex]);
  471. cells[columnIndex] = cell;
  472. }
  473. setRow(rowIndex, cells);
  474. }
  475. @Override
  476. public void setRowTexts(final int rowIndex, final List<String> cellTexts) {
  477. Assert.paramNotNull(cellTexts, "cellTexts");
  478. final ITableCell[] cells = new ITableCell[cellTexts.size()];
  479. int columnIndex = 0;
  480. for (final String cellText : cellTexts) {
  481. final TableCell cell = new TableCell(getCell(rowIndex, columnIndex));
  482. cell.setText(cellText);
  483. cells[columnIndex] = cell;
  484. columnIndex++;
  485. }
  486. setRow(rowIndex, cells);
  487. }
  488. @Override
  489. public void removeRows(final List<Integer> rows) {
  490. final int[] rowsArray = new int[rows.size()];
  491. int index = 0;
  492. for (final Integer row : rows) {
  493. rowsArray[index] = row.intValue();
  494. index++;
  495. }
  496. removeRows(rowsArray);
  497. }
  498. ////////////////////////////////////////////////////////////////////////////////////////////////
  499. //Convenience methods end
  500. ////////////////////////////////////////////////////////////////////////////////////////////////
  501. private ITableCellBuilder cellBuilder() {
  502. return new TableCellBuilder().setEditable(cellsEditableDefault);
  503. }
  504. }