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.

StaticSection.java 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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.ui.components.grid;
  17. import java.io.Serializable;
  18. import java.util.ArrayList;
  19. import java.util.LinkedHashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.Objects;
  23. import com.vaadin.shared.ui.grid.SectionState;
  24. import com.vaadin.shared.ui.grid.SectionState.CellState;
  25. import com.vaadin.shared.ui.grid.SectionState.RowState;
  26. /**
  27. * Represents the header or footer section of a Grid.
  28. *
  29. * @author Vaadin Ltd.
  30. *
  31. * @param <ROW>
  32. * the type of the rows in the section
  33. *
  34. * @since 8.0
  35. */
  36. public abstract class StaticSection<ROW extends StaticSection.StaticRow<?>>
  37. implements Serializable {
  38. /**
  39. * Abstract base class for Grid header and footer rows.
  40. *
  41. * @param <CELL>
  42. * the type of the cells in the row
  43. */
  44. public abstract static class StaticRow<CELL extends StaticCell>
  45. implements Serializable {
  46. private RowState rowState = new RowState();
  47. private StaticSection<?> section;
  48. private Map<Object, CELL> cells = new LinkedHashMap<>();
  49. /**
  50. * Creates a new row belonging to the given section.
  51. *
  52. * @param section
  53. * the section of the row
  54. */
  55. protected StaticRow(StaticSection<?> section) {
  56. this.section = section;
  57. }
  58. /**
  59. * Creates and returns a new instance of the cell type.
  60. *
  61. * @return the created cell
  62. */
  63. protected abstract CELL createCell();
  64. /**
  65. * Returns the declarative tag name used for the cells in this row.
  66. *
  67. * @return the cell tag name
  68. */
  69. protected abstract String getCellTagName();
  70. /**
  71. * Adds a cell to this section, corresponding to the given column id.
  72. *
  73. * @param columnId
  74. * the id of the column for which to add a cell
  75. */
  76. protected void addCell(String columnId) {
  77. CELL cell = createCell();
  78. cell.setColumnId(columnId);
  79. cells.put(columnId, cell);
  80. rowState.cells.put(columnId, cell.getCellState());
  81. }
  82. /**
  83. * Removes the cell from this section that corresponds to the given
  84. * column id. If there is no such cell, does nothing.
  85. *
  86. * @param columnId
  87. * the id of the column from which to remove the cell
  88. */
  89. protected void removeCell(Object columnId) {
  90. CELL cell = cells.remove(columnId);
  91. if (cell != null) {
  92. rowState.cells.remove(cell.getCellState());
  93. }
  94. }
  95. /**
  96. * Returns the shared state of this row.
  97. *
  98. * @return the row state
  99. */
  100. protected RowState getRowState() {
  101. return rowState;
  102. }
  103. /**
  104. * Returns the cell in this section that corresponds to the given column
  105. * id.
  106. *
  107. * @param columnId
  108. * the id of the column
  109. * @return the cell for the given column or null if not found
  110. */
  111. public CELL getCell(String columnId) {
  112. CELL cell = cells.get(columnId);
  113. return cell;
  114. }
  115. }
  116. /**
  117. * A header or footer cell. Has a simple textual caption.
  118. */
  119. abstract static class StaticCell implements Serializable {
  120. private CellState cellState = new CellState();
  121. private StaticRow<?> row;
  122. protected StaticCell(StaticRow<?> row) {
  123. this.row = row;
  124. }
  125. void setColumnId(String id) {
  126. cellState.columnId = id;
  127. }
  128. String getColumnId() {
  129. return cellState.columnId;
  130. }
  131. /**
  132. * Gets the row where this cell is.
  133. *
  134. * @return row for this cell
  135. */
  136. public StaticRow<?> getRow() {
  137. return row;
  138. }
  139. /**
  140. * Returns the shared state of this cell.
  141. *
  142. * @return the cell state
  143. */
  144. protected CellState getCellState() {
  145. return cellState;
  146. }
  147. /**
  148. * Sets the textual caption of this cell.
  149. *
  150. * @param text
  151. * a plain text caption, not null
  152. */
  153. public void setText(String text) {
  154. Objects.requireNonNull(text, "text cannot be null");
  155. cellState.text = text;
  156. row.section.markAsDirty();
  157. }
  158. /**
  159. * Returns the textual caption of this cell.
  160. *
  161. * @return the plain text caption
  162. */
  163. public String getText() {
  164. return cellState.text;
  165. }
  166. }
  167. private List<ROW> rows = new ArrayList<>();
  168. /**
  169. * Creates a new row instance.
  170. *
  171. * @return the new row
  172. */
  173. protected abstract ROW createRow();
  174. /**
  175. * Returns the shared state of this section.
  176. *
  177. * @param markAsDirty
  178. * {@code true} to mark the state as modified, {@code false}
  179. * otherwise
  180. * @return the section state
  181. */
  182. protected abstract SectionState getState(boolean markAsDirty);
  183. /**
  184. * Marks the state of this section as modified.
  185. */
  186. protected void markAsDirty() {
  187. getState(true);
  188. }
  189. /**
  190. * Adds a new row at the given index.
  191. *
  192. * @param index
  193. * the index of the new row
  194. * @return the added row
  195. * @throws IndexOutOfBoundsException
  196. * if {@code index < 0 || index > getRowCount()}
  197. */
  198. public ROW addRowAt(int index) {
  199. ROW row = createRow();
  200. rows.add(index, row);
  201. getState(true).rows.add(index, row.getRowState());
  202. return row;
  203. }
  204. /**
  205. * Removes the row at the given index.
  206. *
  207. * @param index
  208. * the index of the row to remove
  209. * @throws IndexOutOfBoundsException
  210. * if {@code index < 0 || index >= getRowCount()}
  211. */
  212. public void removeRow(int index) {
  213. rows.remove(index);
  214. getState(true).rows.remove(index);
  215. }
  216. /**
  217. * Removes the given row from this section.
  218. *
  219. * @param row
  220. * the row to remove, not null
  221. * @throws IllegalArgumentException
  222. * if this section does not contain the row
  223. */
  224. public void removeRow(Object row) {
  225. Objects.requireNonNull(row, "row cannot be null");
  226. int index = rows.indexOf(row);
  227. if (index < 0) {
  228. throw new IllegalArgumentException(
  229. "Section does not contain the given row");
  230. }
  231. removeRow(index);
  232. }
  233. /**
  234. * Returns the row at the given index.
  235. *
  236. * @param index
  237. * the index of the row
  238. * @return the row at the index
  239. * @throws IndexOutOfBoundsException
  240. * if {@code index < 0 || index >= getRowCount()}
  241. */
  242. public ROW getRow(int index) {
  243. return rows.get(index);
  244. }
  245. /**
  246. * Returns the number of rows in this section.
  247. *
  248. * @return the number of rows
  249. */
  250. public int getRowCount() {
  251. return rows.size();
  252. }
  253. /**
  254. * Adds a cell corresponding to the given column id to this section.
  255. *
  256. * @param columnId
  257. * the id of the column for which to add a cell
  258. */
  259. public void addColumn(String columnId) {
  260. for (ROW row : rows) {
  261. row.addCell(columnId);
  262. }
  263. }
  264. /**
  265. * Removes the cell corresponding to the given column id.
  266. *
  267. * @param columnId
  268. * the id of the column whose cell to remove
  269. */
  270. public void removeColumn(String columnId) {
  271. for (ROW row : rows) {
  272. row.removeCell(columnId);
  273. }
  274. }
  275. }