Change build scripts
[jvcard.git] / src / com / googlecode / lanterna / gui2 / table / TableModel.java
CommitLineData
a3b510ab
NR
1package com.googlecode.lanterna.gui2.table;
2
3import java.util.*;
4
5/**
6 * A {@code TableModel} contains the data model behind a table, here is where all the action cell values and header
7 * labels are stored.
8 *
9 * @author Martin
10 */
11public class TableModel<V> {
12 private final List<String> columns;
13 private final List<List<V>> rows;
14
15 /**
16 * Default constructor, creates a new model with same number of columns as labels supplied
17 * @param columnLabels Labels for the column headers
18 */
19 public TableModel(String... columnLabels) {
20 this.columns = new ArrayList<String>(Arrays.asList(columnLabels));
21 this.rows = new ArrayList<List<V>>();
22 }
23
24 /**
25 * Returns the number of columns in the model
26 * @return Number of columns in the model
27 */
28 public synchronized int getColumnCount() {
29 return columns.size();
30 }
31
32 /**
33 * Returns number of rows in the model
34 * @return Number of rows in the model
35 */
36 public synchronized int getRowCount() {
37 return rows.size();
38 }
39
40 /**
41 * Returns all rows in the model as a list of lists containing the data as elements
42 * @return All rows in the model as a list of lists containing the data as elements
43 */
44 public synchronized List<List<V>> getRows() {
45 List<List<V>> copy = new ArrayList<List<V>>();
46 for(List<V> row: rows) {
47 copy.add(new ArrayList<V>(row));
48 }
49 return copy;
50 }
51
52 /**
53 * Returns all column header label as a list of strings
54 * @return All column header label as a list of strings
55 */
56 public synchronized List<String> getColumnLabels() {
57 return new ArrayList<String>(columns);
58 }
59
60 /**
61 * Returns a row from the table as a list of the cell data
62 * @param index Index of the row to return
63 * @return Row from the table as a list of the cell data
64 */
65 public synchronized List<V> getRow(int index) {
66 return new ArrayList<V>(rows.get(index));
67 }
68
69 /**
70 * Adds a new row to the table model at the end
71 * @param values Data to associate with the new row, mapped column by column in order
72 * @return Itself
73 */
74 public synchronized TableModel<V> addRow(V... values) {
75 addRow(Arrays.asList(values));
76 return this;
77 }
78
79 /**
80 * Adds a new row to the table model at the end
81 * @param values Data to associate with the new row, mapped column by column in order
82 * @return Itself
83 */
84 public synchronized TableModel<V> addRow(Collection<V> values) {
85 insertRow(getRowCount(), values);
86 return this;
87 }
88
89 /**
90 * Inserts a new row to the table model at a particular index
91 * @param index Index the new row should have, 0 means the first row and <i>row count</i> will append the row at the
92 * end
93 * @param values Data to associate with the new row, mapped column by column in order
94 * @return Itself
95 */
96 public synchronized TableModel<V> insertRow(int index, Collection<V> values) {
97 ArrayList<V> list = new ArrayList<V>(values);
98 rows.add(index, list);
99 return this;
100 }
101
102 /**
103 * Removes a row at a particular index from the table model
104 * @param index Index of the row to remove
105 * @return Itself
106 */
107 public synchronized TableModel<V> removeRow(int index) {
108 rows.remove(index);
109 return this;
110 }
111
112 /**
113 * Returns the label of a column header
114 * @param index Index of the column to retrieve the header label for
115 * @return Label of the column selected
116 */
117 public synchronized String getColumnLabel(int index) {
118 return columns.get(index);
119 }
120
121 /**
122 * Updates the label of a column header
123 * @param index Index of the column to update the header label for
124 * @param newLabel New label to assign to the column header
125 * @return Itself
126 */
127 public synchronized TableModel<V> setColumnLabel(int index, String newLabel) {
128 columns.set(index, newLabel);
129 return this;
130 }
131
132 /**
133 * Adds a new column into the table model as the last column. You can optionally supply values for the existing rows
134 * through the {@code newColumnValues}.
135 * @param label Label for the header of the new column
136 * @param newColumnValues Optional values to assign to the existing rows, where the first element in the array will
137 * be the value of the first row and so on...
138 * @return Itself
139 */
140 public synchronized TableModel<V> addColumn(String label, V[] newColumnValues) {
141 return insertColumn(getColumnCount(), label, newColumnValues);
142 }
143
144 /**
145 * Adds a new column into the table model at a specified index. You can optionally supply values for the existing
146 * rows through the {@code newColumnValues}.
147 * @param index Index for the new column
148 * @param label Label for the header of the new column
149 * @param newColumnValues Optional values to assign to the existing rows, where the first element in the array will
150 * be the value of the first row and so on...
151 * @return Itself
152 */
153 public synchronized TableModel<V> insertColumn(int index, String label, V[] newColumnValues) {
154 columns.add(index, label);
155 for(int i = 0; i < rows.size(); i++) {
156 List<V> row = rows.get(i);
157
158 //Pad row with null if necessary
159 for(int j = row.size(); j < index; j++) {
160 row.add(null);
161 }
162
163 if(newColumnValues != null && i < newColumnValues.length && newColumnValues[i] != null) {
164 row.add(index, newColumnValues[i]);
165 }
166 else {
167 row.add(index, null);
168 }
169 }
170 return this;
171 }
172
173 /**
174 * Removes a column from the table model
175 * @param index Index of the column to remove
176 * @return Itself
177 */
178 public synchronized TableModel<V> removeColumn(int index) {
179 columns.remove(index);
180 for(List<V> row : rows) {
181 row.remove(index);
182 }
183 return this;
184 }
185
186 /**
187 * Returns the cell value stored at a specific column/row coordinate.
188 * @param columnIndex Column index of the cell
189 * @param rowIndex Row index of the cell
190 * @return The data value stored in this cell
191 */
192 public synchronized V getCell(int columnIndex, int rowIndex) {
193 if(rowIndex < 0 || columnIndex < 0) {
194 throw new IndexOutOfBoundsException("Invalid row or column index: " + rowIndex + " " + columnIndex);
195 }
196 else if (rowIndex >= getRowCount()) {
197 throw new IndexOutOfBoundsException("TableModel has " + getRowCount() + " rows, invalid access at rowIndex " + rowIndex);
198 }
199 if(columnIndex >= getColumnCount()) {
200 throw new IndexOutOfBoundsException("TableModel has " + columnIndex + " columns, invalid access at columnIndex " + columnIndex);
201 }
202 return rows.get(rowIndex).get(columnIndex);
203 }
204
205 /**
206 * Updates the call value stored at a specific column/row coordinate.
207 * @param columnIndex Column index of the cell
208 * @param rowIndex Row index of the cell
209 * @param value New value to assign to the cell
210 * @return Itself
211 */
212 public synchronized TableModel<V> setCell(int columnIndex, int rowIndex, V value) {
213 getCell(columnIndex, rowIndex);
214 List<V> row = rows.get(rowIndex);
215
216 //Pad row with null if necessary
217 for(int j = row.size(); j < columnIndex; j++) {
218 row.add(null);
219 }
220
221 V existingValue = row.get(columnIndex);
222 if(existingValue == value) {
223 return this;
224 }
225 row.set(columnIndex, value);
226 return this;
227 }
228}