53 * of all JavaBeans™
54 * has been added to the <code>java.beans</code> package.
55 * Please see {@link java.beans.XMLEncoder}.
56 *
57 * @author Philip Milne
58 *
59 * @see TableModel
60 * @see #getDataVector
61 */
62 @SuppressWarnings("serial") // Same-version serialization only
63 public class DefaultTableModel extends AbstractTableModel implements Serializable {
64
65 //
66 // Instance Variables
67 //
68
69 /**
70 * The <code>Vector</code> of <code>Vectors</code> of
71 * <code>Object</code> values.
72 */
73 protected Vector dataVector;
74
75 /** The <code>Vector</code> of column identifiers. */
76 protected Vector columnIdentifiers;
77
78 //
79 // Constructors
80 //
81
82 /**
83 * Constructs a default <code>DefaultTableModel</code>
84 * which is a table of zero columns and zero rows.
85 */
86 public DefaultTableModel() {
87 this(0, 0);
88 }
89
90 private static Vector newVector(int size) {
91 Vector v = new Vector(size);
92 v.setSize(size);
93 return v;
94 }
95
96 /**
97 * Constructs a <code>DefaultTableModel</code> with
98 * <code>rowCount</code> and <code>columnCount</code> of
99 * <code>null</code> object values.
100 *
101 * @param rowCount the number of rows the table holds
102 * @param columnCount the number of columns the table holds
103 *
104 * @see #setValueAt
105 */
106 public DefaultTableModel(int rowCount, int columnCount) {
107 this(newVector(columnCount), rowCount);
108 }
109
110 /**
111 * Constructs a <code>DefaultTableModel</code> with as many columns
112 * as there are elements in <code>columnNames</code>
113 * and <code>rowCount</code> of <code>null</code>
114 * object values. Each column's name will be taken from
115 * the <code>columnNames</code> vector.
116 *
117 * @param columnNames <code>vector</code> containing the names
118 * of the new columns; if this is
119 * <code>null</code> then the model has no columns
120 * @param rowCount the number of rows the table holds
121 * @see #setDataVector
122 * @see #setValueAt
123 */
124 public DefaultTableModel(Vector columnNames, int rowCount) {
125 setDataVector(newVector(rowCount), columnNames);
126 }
127
128 /**
129 * Constructs a <code>DefaultTableModel</code> with as many
130 * columns as there are elements in <code>columnNames</code>
131 * and <code>rowCount</code> of <code>null</code>
132 * object values. Each column's name will be taken from
133 * the <code>columnNames</code> array.
134 *
135 * @param columnNames <code>array</code> containing the names
136 * of the new columns; if this is
137 * <code>null</code> then the model has no columns
138 * @param rowCount the number of rows the table holds
139 * @see #setDataVector
140 * @see #setValueAt
141 */
142 public DefaultTableModel(Object[] columnNames, int rowCount) {
143 this(convertToVector(columnNames), rowCount);
144 }
145
146 /**
147 * Constructs a <code>DefaultTableModel</code> and initializes the table
148 * by passing <code>data</code> and <code>columnNames</code>
149 * to the <code>setDataVector</code> method.
150 *
151 * @param data the data of the table, a <code>Vector</code>
152 * of <code>Vector</code>s of <code>Object</code>
153 * values
154 * @param columnNames <code>vector</code> containing the names
155 * of the new columns
156 * @see #getDataVector
157 * @see #setDataVector
158 */
159 public DefaultTableModel(Vector data, Vector columnNames) {
160 setDataVector(data, columnNames);
161 }
162
163 /**
164 * Constructs a <code>DefaultTableModel</code> and initializes the table
165 * by passing <code>data</code> and <code>columnNames</code>
166 * to the <code>setDataVector</code>
167 * method. The first index in the <code>Object[][]</code> array is
168 * the row index and the second is the column index.
169 *
170 * @param data the data of the table
171 * @param columnNames the names of the columns
172 * @see #getDataVector
173 * @see #setDataVector
174 */
175 public DefaultTableModel(Object[][] data, Object[] columnNames) {
176 setDataVector(data, columnNames);
177 }
178
179 /**
180 * Returns the <code>Vector</code> of <code>Vectors</code>
181 * that contains the table's
182 * data values. The vectors contained in the outer vector are
183 * each a single row of values. In other words, to get to the cell
184 * at row 1, column 5: <p>
185 *
186 * <code>((Vector)getDataVector().elementAt(1)).elementAt(5);</code>
187 *
188 * @return the vector of vectors containing the tables data values
189 *
190 * @see #newDataAvailable
191 * @see #newRowsAdded
192 * @see #setDataVector
193 */
194 public Vector getDataVector() {
195 return dataVector;
196 }
197
198 private static Vector nonNullVector(Vector v) {
199 return (v != null) ? v : new Vector();
200 }
201
202 /**
203 * Replaces the current <code>dataVector</code> instance variable
204 * with the new <code>Vector</code> of rows, <code>dataVector</code>.
205 * Each row is represented in <code>dataVector</code> as a
206 * <code>Vector</code> of <code>Object</code> values.
207 * <code>columnIdentifiers</code> are the names of the new
208 * columns. The first name in <code>columnIdentifiers</code> is
209 * mapped to column 0 in <code>dataVector</code>. Each row in
210 * <code>dataVector</code> is adjusted to match the number of
211 * columns in <code>columnIdentifiers</code>
212 * either by truncating the <code>Vector</code> if it is too long,
213 * or adding <code>null</code> values if it is too short.
214 * <p>Note that passing in a <code>null</code> value for
215 * <code>dataVector</code> results in unspecified behavior,
216 * an possibly an exception.
217 *
218 * @param dataVector the new data vector
219 * @param columnIdentifiers the names of the columns
220 * @see #getDataVector
221 */
222 public void setDataVector(Vector dataVector, Vector columnIdentifiers) {
223 this.dataVector = nonNullVector(dataVector);
224 this.columnIdentifiers = nonNullVector(columnIdentifiers);
225 justifyRows(0, getRowCount());
226 fireTableStructureChanged();
227 }
228
229 /**
230 * Replaces the value in the <code>dataVector</code> instance
231 * variable with the values in the array <code>dataVector</code>.
232 * The first index in the <code>Object[][]</code>
233 * array is the row index and the second is the column index.
234 * <code>columnIdentifiers</code> are the names of the new columns.
235 *
236 * @param dataVector the new data vector
237 * @param columnIdentifiers the names of the columns
238 * @see #setDataVector(Vector, Vector)
239 */
240 public void setDataVector(Object[][] dataVector, Object[] columnIdentifiers) {
241 setDataVector(convertToVector(dataVector), convertToVector(columnIdentifiers));
242 }
247 * @param event the change event
248 *
249 */
250 public void newDataAvailable(TableModelEvent event) {
251 fireTableChanged(event);
252 }
253
254 //
255 // Manipulating rows
256 //
257
258 private void justifyRows(int from, int to) {
259 // Sometimes the DefaultTableModel is subclassed
260 // instead of the AbstractTableModel by mistake.
261 // Set the number of rows for the case when getRowCount
262 // is overridden.
263 dataVector.setSize(getRowCount());
264
265 for (int i = from; i < to; i++) {
266 if (dataVector.elementAt(i) == null) {
267 dataVector.setElementAt(new Vector(), i);
268 }
269 ((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
270 }
271 }
272
273 /**
274 * Ensures that the new rows have the correct number of columns.
275 * This is accomplished by using the <code>setSize</code> method in
276 * <code>Vector</code> which truncates vectors
277 * which are too long, and appends <code>null</code>s if they
278 * are too short.
279 * This method also sends out a <code>tableChanged</code>
280 * notification message to all the listeners.
281 *
282 * @param e this <code>TableModelEvent</code> describes
283 * where the rows were added.
284 * If <code>null</code> it assumes
285 * all the rows were newly added
286 * @see #getDataVector
287 */
332 * than the current size, new rows are added to the end of the model
333 * If the new size is less than the current size, all
334 * rows at index <code>rowCount</code> and greater are discarded.
335 *
336 * @see #setColumnCount
337 * @since 1.3
338 *
339 * @param rowCount number of rows in the model
340 */
341 public void setRowCount(int rowCount) {
342 setNumRows(rowCount);
343 }
344
345 /**
346 * Adds a row to the end of the model. The new row will contain
347 * <code>null</code> values unless <code>rowData</code> is specified.
348 * Notification of the row being added will be generated.
349 *
350 * @param rowData optional data of the row being added
351 */
352 public void addRow(Vector rowData) {
353 insertRow(getRowCount(), rowData);
354 }
355
356 /**
357 * Adds a row to the end of the model. The new row will contain
358 * <code>null</code> values unless <code>rowData</code> is specified.
359 * Notification of the row being added will be generated.
360 *
361 * @param rowData optional data of the row being added
362 */
363 public void addRow(Object[] rowData) {
364 addRow(convertToVector(rowData));
365 }
366
367 /**
368 * Inserts a row at <code>row</code> in the model. The new row
369 * will contain <code>null</code> values unless <code>rowData</code>
370 * is specified. Notification of the row being added will be generated.
371 *
372 * @param row the row index of the row to be inserted
373 * @param rowData optional data of the row being added
374 * @exception ArrayIndexOutOfBoundsException if the row was invalid
375 */
376 public void insertRow(int row, Vector rowData) {
377 dataVector.insertElementAt(rowData, row);
378 justifyRows(row, row+1);
379 fireTableRowsInserted(row, row);
380 }
381
382 /**
383 * Inserts a row at <code>row</code> in the model. The new row
384 * will contain <code>null</code> values unless <code>rowData</code>
385 * is specified. Notification of the row being added will be generated.
386 *
387 * @param row the row index of the row to be inserted
388 * @param rowData optional data of the row being added
389 * @exception ArrayIndexOutOfBoundsException if the row was invalid
390 */
391 public void insertRow(int row, Object[] rowData) {
392 insertRow(row, convertToVector(rowData));
393 }
394
395 private static int gcd(int i, int j) {
396 return (j == 0) ? i : gcd(j, i%j);
397 }
398
399 private static void rotate(Vector v, int a, int b, int shift) {
400 int size = b - a;
401 int r = size - shift;
402 int g = gcd(size, r);
403 for(int i = 0; i < g; i++) {
404 int to = i;
405 Object tmp = v.elementAt(a + to);
406 for(int from = (to + r) % size; from != i; from = (to + r) % size) {
407 v.setElementAt(v.elementAt(a + from), a + to);
408 to = from;
409 }
410 v.setElementAt(tmp, a + to);
411 }
412 }
413
414 /**
415 * Moves one or more rows from the inclusive range <code>start</code> to
416 * <code>end</code> to the <code>to</code> position in the model.
417 * After the move, the row that was at index <code>start</code>
418 * will be at index <code>to</code>.
419 * This method will send a <code>tableChanged</code> notification
420 message to all the listeners.
421 *
422 * <pre>
423 * Examples of moves:
424 *
425 * 1. moveRow(1,3,5);
466 fireTableRowsDeleted(row, row);
467 }
468
469 //
470 // Manipulating columns
471 //
472
473 /**
474 * Replaces the column identifiers in the model. If the number of
475 * <code>newIdentifier</code>s is greater than the current number
476 * of columns, new columns are added to the end of each row in the model.
477 * If the number of <code>newIdentifier</code>s is less than the current
478 * number of columns, all the extra columns at the end of a row are
479 * discarded.
480 *
481 * @param columnIdentifiers vector of column identifiers. If
482 * <code>null</code>, set the model
483 * to zero columns
484 * @see #setNumRows
485 */
486 public void setColumnIdentifiers(Vector columnIdentifiers) {
487 setDataVector(dataVector, columnIdentifiers);
488 }
489
490 /**
491 * Replaces the column identifiers in the model. If the number of
492 * <code>newIdentifier</code>s is greater than the current number
493 * of columns, new columns are added to the end of each row in the model.
494 * If the number of <code>newIdentifier</code>s is less than the current
495 * number of columns, all the extra columns at the end of a row are
496 * discarded.
497 *
498 * @param newIdentifiers array of column identifiers.
499 * If <code>null</code>, set
500 * the model to zero columns
501 * @see #setNumRows
502 */
503 public void setColumnIdentifiers(Object[] newIdentifiers) {
504 setColumnIdentifiers(convertToVector(newIdentifiers));
505 }
506
516 * @see #setColumnCount
517 * @since 1.3
518 */
519 public void setColumnCount(int columnCount) {
520 columnIdentifiers.setSize(columnCount);
521 justifyRows(0, getRowCount());
522 fireTableStructureChanged();
523 }
524
525 /**
526 * Adds a column to the model. The new column will have the
527 * identifier <code>columnName</code>, which may be null. This method
528 * will send a
529 * <code>tableChanged</code> notification message to all the listeners.
530 * This method is a cover for <code>addColumn(Object, Vector)</code> which
531 * uses <code>null</code> as the data vector.
532 *
533 * @param columnName the identifier of the column being added
534 */
535 public void addColumn(Object columnName) {
536 addColumn(columnName, (Vector)null);
537 }
538
539 /**
540 * Adds a column to the model. The new column will have the
541 * identifier <code>columnName</code>, which may be null.
542 * <code>columnData</code> is the
543 * optional vector of data for the column. If it is <code>null</code>
544 * the column is filled with <code>null</code> values. Otherwise,
545 * the new data will be added to model starting with the first
546 * element going to row 0, etc. This method will send a
547 * <code>tableChanged</code> notification message to all the listeners.
548 *
549 * @param columnName the identifier of the column being added
550 * @param columnData optional data of the column being added
551 */
552 public void addColumn(Object columnName, Vector columnData) {
553 columnIdentifiers.addElement(columnName);
554 if (columnData != null) {
555 int columnSize = columnData.size();
556 if (columnSize > getRowCount()) {
557 dataVector.setSize(columnSize);
558 }
559 justifyRows(0, getRowCount());
560 int newColumn = getColumnCount() - 1;
561 for(int i = 0; i < columnSize; i++) {
562 Vector row = (Vector)dataVector.elementAt(i);
563 row.setElementAt(columnData.elementAt(i), newColumn);
564 }
565 }
566 else {
567 justifyRows(0, getRowCount());
568 }
569
570 fireTableStructureChanged();
571 }
572
573 /**
574 * Adds a column to the model. The new column will have the
575 * identifier <code>columnName</code>. <code>columnData</code> is the
576 * optional array of data for the column. If it is <code>null</code>
577 * the column is filled with <code>null</code> values. Otherwise,
578 * the new data will be added to model starting with the first
579 * element going to row 0, etc. This method will send a
580 * <code>tableChanged</code> notification message to all the listeners.
581 *
582 * @param columnName identifier of the newly created column
634 * @param row the row whose value is to be queried
635 * @param column the column whose value is to be queried
636 * @return true
637 * @see #setValueAt
638 */
639 public boolean isCellEditable(int row, int column) {
640 return true;
641 }
642
643 /**
644 * Returns an attribute value for the cell at <code>row</code>
645 * and <code>column</code>.
646 *
647 * @param row the row whose value is to be queried
648 * @param column the column whose value is to be queried
649 * @return the value Object at the specified cell
650 * @exception ArrayIndexOutOfBoundsException if an invalid row or
651 * column was given
652 */
653 public Object getValueAt(int row, int column) {
654 Vector rowVector = (Vector)dataVector.elementAt(row);
655 return rowVector.elementAt(column);
656 }
657
658 /**
659 * Sets the object value for the cell at <code>column</code> and
660 * <code>row</code>. <code>aValue</code> is the new value. This method
661 * will generate a <code>tableChanged</code> notification.
662 *
663 * @param aValue the new value; this can be null
664 * @param row the row whose value is to be changed
665 * @param column the column whose value is to be changed
666 * @exception ArrayIndexOutOfBoundsException if an invalid row or
667 * column was given
668 */
669 public void setValueAt(Object aValue, int row, int column) {
670 Vector rowVector = (Vector)dataVector.elementAt(row);
671 rowVector.setElementAt(aValue, column);
672 fireTableCellUpdated(row, column);
673 }
674
675 //
676 // Protected Methods
677 //
678
679 /**
680 * Returns a vector that contains the same objects as the array.
681 * @param anArray the array to be converted
682 * @return the new vector; if <code>anArray</code> is <code>null</code>,
683 * returns <code>null</code>
684 */
685 protected static Vector convertToVector(Object[] anArray) {
686 if (anArray == null) {
687 return null;
688 }
689 Vector<Object> v = new Vector<Object>(anArray.length);
690 for (Object o : anArray) {
691 v.addElement(o);
692 }
693 return v;
694 }
695
696 /**
697 * Returns a vector of vectors that contains the same objects as the array.
698 * @param anArray the double array to be converted
699 * @return the new vector of vectors; if <code>anArray</code> is
700 * <code>null</code>, returns <code>null</code>
701 */
702 protected static Vector convertToVector(Object[][] anArray) {
703 if (anArray == null) {
704 return null;
705 }
706 Vector<Vector> v = new Vector<Vector>(anArray.length);
707 for (Object[] o : anArray) {
708 v.addElement(convertToVector(o));
709 }
710 return v;
711 }
712
713 } // End of class DefaultTableModel
|
53 * of all JavaBeans™
54 * has been added to the <code>java.beans</code> package.
55 * Please see {@link java.beans.XMLEncoder}.
56 *
57 * @author Philip Milne
58 *
59 * @see TableModel
60 * @see #getDataVector
61 */
62 @SuppressWarnings("serial") // Same-version serialization only
63 public class DefaultTableModel extends AbstractTableModel implements Serializable {
64
65 //
66 // Instance Variables
67 //
68
69 /**
70 * The <code>Vector</code> of <code>Vectors</code> of
71 * <code>Object</code> values.
72 */
73 protected Vector<Vector<Object>> dataVector;
74
75 /** The <code>Vector</code> of column identifiers. */
76 protected Vector<Object> columnIdentifiers;
77
78 //
79 // Constructors
80 //
81
82 /**
83 * Constructs a default <code>DefaultTableModel</code>
84 * which is a table of zero columns and zero rows.
85 */
86 public DefaultTableModel() {
87 this(0, 0);
88 }
89
90 private static <E> Vector<E> newVector(int size) {
91 Vector<E> v = new Vector<>(size);
92 v.setSize(size);
93 return v;
94 }
95
96 /**
97 * Constructs a <code>DefaultTableModel</code> with
98 * <code>rowCount</code> and <code>columnCount</code> of
99 * <code>null</code> object values.
100 *
101 * @param rowCount the number of rows the table holds
102 * @param columnCount the number of columns the table holds
103 *
104 * @see #setValueAt
105 */
106 public DefaultTableModel(int rowCount, int columnCount) {
107 this(newVector(columnCount), rowCount);
108 }
109
110 /**
111 * Constructs a <code>DefaultTableModel</code> with as many columns
112 * as there are elements in <code>columnNames</code>
113 * and <code>rowCount</code> of <code>null</code>
114 * object values. Each column's name will be taken from
115 * the <code>columnNames</code> vector.
116 *
117 * @param columnNames <code>vector</code> containing the names
118 * of the new columns; if this is
119 * <code>null</code> then the model has no columns
120 * @param rowCount the number of rows the table holds
121 * @see #setDataVector
122 * @see #setValueAt
123 */
124 public DefaultTableModel(Vector<Object> columnNames, int rowCount) {
125 setDataVector(newVector(rowCount), columnNames);
126 }
127
128 /**
129 * Constructs a <code>DefaultTableModel</code> with as many
130 * columns as there are elements in <code>columnNames</code>
131 * and <code>rowCount</code> of <code>null</code>
132 * object values. Each column's name will be taken from
133 * the <code>columnNames</code> array.
134 *
135 * @param columnNames <code>array</code> containing the names
136 * of the new columns; if this is
137 * <code>null</code> then the model has no columns
138 * @param rowCount the number of rows the table holds
139 * @see #setDataVector
140 * @see #setValueAt
141 */
142 public DefaultTableModel(Object[] columnNames, int rowCount) {
143 this(convertToVector(columnNames), rowCount);
144 }
145
146 /**
147 * Constructs a <code>DefaultTableModel</code> and initializes the table
148 * by passing <code>data</code> and <code>columnNames</code>
149 * to the <code>setDataVector</code> method.
150 *
151 * @param data the data of the table, a <code>Vector</code>
152 * of <code>Vector</code>s of <code>Object</code>
153 * values
154 * @param columnNames <code>vector</code> containing the names
155 * of the new columns
156 * @see #getDataVector
157 * @see #setDataVector
158 */
159 public DefaultTableModel(Vector<Vector<Object>> data, Vector<Object> columnNames) {
160 setDataVector(data, columnNames);
161 }
162
163 /**
164 * Constructs a <code>DefaultTableModel</code> and initializes the table
165 * by passing <code>data</code> and <code>columnNames</code>
166 * to the <code>setDataVector</code>
167 * method. The first index in the <code>Object[][]</code> array is
168 * the row index and the second is the column index.
169 *
170 * @param data the data of the table
171 * @param columnNames the names of the columns
172 * @see #getDataVector
173 * @see #setDataVector
174 */
175 public DefaultTableModel(Object[][] data, Object[] columnNames) {
176 setDataVector(data, columnNames);
177 }
178
179 /**
180 * Returns the <code>Vector</code> of <code>Vectors</code>
181 * that contains the table's
182 * data values. The vectors contained in the outer vector are
183 * each a single row of values. In other words, to get to the cell
184 * at row 1, column 5: <p>
185 *
186 * <code>((Vector)getDataVector().elementAt(1)).elementAt(5);</code>
187 *
188 * @return the vector of vectors containing the tables data values
189 *
190 * @see #newDataAvailable
191 * @see #newRowsAdded
192 * @see #setDataVector
193 */
194 public Vector<Vector<Object>> getDataVector() {
195 return dataVector;
196 }
197
198 private static <E> Vector<E> nonNullVector(Vector<E> v) {
199 return (v != null) ? v : new Vector<>();
200 }
201
202 /**
203 * Replaces the current <code>dataVector</code> instance variable
204 * with the new <code>Vector</code> of rows, <code>dataVector</code>.
205 * Each row is represented in <code>dataVector</code> as a
206 * <code>Vector</code> of <code>Object</code> values.
207 * <code>columnIdentifiers</code> are the names of the new
208 * columns. The first name in <code>columnIdentifiers</code> is
209 * mapped to column 0 in <code>dataVector</code>. Each row in
210 * <code>dataVector</code> is adjusted to match the number of
211 * columns in <code>columnIdentifiers</code>
212 * either by truncating the <code>Vector</code> if it is too long,
213 * or adding <code>null</code> values if it is too short.
214 * <p>Note that passing in a <code>null</code> value for
215 * <code>dataVector</code> results in unspecified behavior,
216 * an possibly an exception.
217 *
218 * @param dataVector the new data vector
219 * @param columnIdentifiers the names of the columns
220 * @see #getDataVector
221 */
222 public void setDataVector(Vector<Vector<Object>> dataVector,
223 Vector<Object> columnIdentifiers) {
224 this.dataVector = nonNullVector(dataVector);
225 this.columnIdentifiers = nonNullVector(columnIdentifiers);
226 justifyRows(0, getRowCount());
227 fireTableStructureChanged();
228 }
229
230 /**
231 * Replaces the value in the <code>dataVector</code> instance
232 * variable with the values in the array <code>dataVector</code>.
233 * The first index in the <code>Object[][]</code>
234 * array is the row index and the second is the column index.
235 * <code>columnIdentifiers</code> are the names of the new columns.
236 *
237 * @param dataVector the new data vector
238 * @param columnIdentifiers the names of the columns
239 * @see #setDataVector(Vector, Vector)
240 */
241 public void setDataVector(Object[][] dataVector, Object[] columnIdentifiers) {
242 setDataVector(convertToVector(dataVector), convertToVector(columnIdentifiers));
243 }
248 * @param event the change event
249 *
250 */
251 public void newDataAvailable(TableModelEvent event) {
252 fireTableChanged(event);
253 }
254
255 //
256 // Manipulating rows
257 //
258
259 private void justifyRows(int from, int to) {
260 // Sometimes the DefaultTableModel is subclassed
261 // instead of the AbstractTableModel by mistake.
262 // Set the number of rows for the case when getRowCount
263 // is overridden.
264 dataVector.setSize(getRowCount());
265
266 for (int i = from; i < to; i++) {
267 if (dataVector.elementAt(i) == null) {
268 dataVector.setElementAt(new Vector<>(), i);
269 }
270 ((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
271 }
272 }
273
274 /**
275 * Ensures that the new rows have the correct number of columns.
276 * This is accomplished by using the <code>setSize</code> method in
277 * <code>Vector</code> which truncates vectors
278 * which are too long, and appends <code>null</code>s if they
279 * are too short.
280 * This method also sends out a <code>tableChanged</code>
281 * notification message to all the listeners.
282 *
283 * @param e this <code>TableModelEvent</code> describes
284 * where the rows were added.
285 * If <code>null</code> it assumes
286 * all the rows were newly added
287 * @see #getDataVector
288 */
333 * than the current size, new rows are added to the end of the model
334 * If the new size is less than the current size, all
335 * rows at index <code>rowCount</code> and greater are discarded.
336 *
337 * @see #setColumnCount
338 * @since 1.3
339 *
340 * @param rowCount number of rows in the model
341 */
342 public void setRowCount(int rowCount) {
343 setNumRows(rowCount);
344 }
345
346 /**
347 * Adds a row to the end of the model. The new row will contain
348 * <code>null</code> values unless <code>rowData</code> is specified.
349 * Notification of the row being added will be generated.
350 *
351 * @param rowData optional data of the row being added
352 */
353 public void addRow(Vector<Object> rowData) {
354 insertRow(getRowCount(), rowData);
355 }
356
357 /**
358 * Adds a row to the end of the model. The new row will contain
359 * <code>null</code> values unless <code>rowData</code> is specified.
360 * Notification of the row being added will be generated.
361 *
362 * @param rowData optional data of the row being added
363 */
364 public void addRow(Object[] rowData) {
365 addRow(convertToVector(rowData));
366 }
367
368 /**
369 * Inserts a row at <code>row</code> in the model. The new row
370 * will contain <code>null</code> values unless <code>rowData</code>
371 * is specified. Notification of the row being added will be generated.
372 *
373 * @param row the row index of the row to be inserted
374 * @param rowData optional data of the row being added
375 * @exception ArrayIndexOutOfBoundsException if the row was invalid
376 */
377 public void insertRow(int row, Vector<Object> rowData) {
378 dataVector.insertElementAt(rowData, row);
379 justifyRows(row, row+1);
380 fireTableRowsInserted(row, row);
381 }
382
383 /**
384 * Inserts a row at <code>row</code> in the model. The new row
385 * will contain <code>null</code> values unless <code>rowData</code>
386 * is specified. Notification of the row being added will be generated.
387 *
388 * @param row the row index of the row to be inserted
389 * @param rowData optional data of the row being added
390 * @exception ArrayIndexOutOfBoundsException if the row was invalid
391 */
392 public void insertRow(int row, Object[] rowData) {
393 insertRow(row, convertToVector(rowData));
394 }
395
396 private static int gcd(int i, int j) {
397 return (j == 0) ? i : gcd(j, i%j);
398 }
399
400 private static <E> void rotate(Vector<E> v, int a, int b, int shift) {
401 int size = b - a;
402 int r = size - shift;
403 int g = gcd(size, r);
404 for(int i = 0; i < g; i++) {
405 int to = i;
406 E tmp = v.elementAt(a + to);
407 for(int from = (to + r) % size; from != i; from = (to + r) % size) {
408 v.setElementAt(v.elementAt(a + from), a + to);
409 to = from;
410 }
411 v.setElementAt(tmp, a + to);
412 }
413 }
414
415 /**
416 * Moves one or more rows from the inclusive range <code>start</code> to
417 * <code>end</code> to the <code>to</code> position in the model.
418 * After the move, the row that was at index <code>start</code>
419 * will be at index <code>to</code>.
420 * This method will send a <code>tableChanged</code> notification
421 message to all the listeners.
422 *
423 * <pre>
424 * Examples of moves:
425 *
426 * 1. moveRow(1,3,5);
467 fireTableRowsDeleted(row, row);
468 }
469
470 //
471 // Manipulating columns
472 //
473
474 /**
475 * Replaces the column identifiers in the model. If the number of
476 * <code>newIdentifier</code>s is greater than the current number
477 * of columns, new columns are added to the end of each row in the model.
478 * If the number of <code>newIdentifier</code>s is less than the current
479 * number of columns, all the extra columns at the end of a row are
480 * discarded.
481 *
482 * @param columnIdentifiers vector of column identifiers. If
483 * <code>null</code>, set the model
484 * to zero columns
485 * @see #setNumRows
486 */
487 public void setColumnIdentifiers(Vector<Object> columnIdentifiers) {
488 setDataVector(dataVector, columnIdentifiers);
489 }
490
491 /**
492 * Replaces the column identifiers in the model. If the number of
493 * <code>newIdentifier</code>s is greater than the current number
494 * of columns, new columns are added to the end of each row in the model.
495 * If the number of <code>newIdentifier</code>s is less than the current
496 * number of columns, all the extra columns at the end of a row are
497 * discarded.
498 *
499 * @param newIdentifiers array of column identifiers.
500 * If <code>null</code>, set
501 * the model to zero columns
502 * @see #setNumRows
503 */
504 public void setColumnIdentifiers(Object[] newIdentifiers) {
505 setColumnIdentifiers(convertToVector(newIdentifiers));
506 }
507
517 * @see #setColumnCount
518 * @since 1.3
519 */
520 public void setColumnCount(int columnCount) {
521 columnIdentifiers.setSize(columnCount);
522 justifyRows(0, getRowCount());
523 fireTableStructureChanged();
524 }
525
526 /**
527 * Adds a column to the model. The new column will have the
528 * identifier <code>columnName</code>, which may be null. This method
529 * will send a
530 * <code>tableChanged</code> notification message to all the listeners.
531 * This method is a cover for <code>addColumn(Object, Vector)</code> which
532 * uses <code>null</code> as the data vector.
533 *
534 * @param columnName the identifier of the column being added
535 */
536 public void addColumn(Object columnName) {
537 addColumn(columnName, (Vector<Object>)null);
538 }
539
540 /**
541 * Adds a column to the model. The new column will have the
542 * identifier <code>columnName</code>, which may be null.
543 * <code>columnData</code> is the
544 * optional vector of data for the column. If it is <code>null</code>
545 * the column is filled with <code>null</code> values. Otherwise,
546 * the new data will be added to model starting with the first
547 * element going to row 0, etc. This method will send a
548 * <code>tableChanged</code> notification message to all the listeners.
549 *
550 * @param columnName the identifier of the column being added
551 * @param columnData optional data of the column being added
552 */
553 public void addColumn(Object columnName, Vector<Object> columnData) {
554 columnIdentifiers.addElement(columnName);
555 if (columnData != null) {
556 int columnSize = columnData.size();
557 if (columnSize > getRowCount()) {
558 dataVector.setSize(columnSize);
559 }
560 justifyRows(0, getRowCount());
561 int newColumn = getColumnCount() - 1;
562 for(int i = 0; i < columnSize; i++) {
563 Vector<Object> row = dataVector.elementAt(i);
564 row.setElementAt(columnData.elementAt(i), newColumn);
565 }
566 }
567 else {
568 justifyRows(0, getRowCount());
569 }
570
571 fireTableStructureChanged();
572 }
573
574 /**
575 * Adds a column to the model. The new column will have the
576 * identifier <code>columnName</code>. <code>columnData</code> is the
577 * optional array of data for the column. If it is <code>null</code>
578 * the column is filled with <code>null</code> values. Otherwise,
579 * the new data will be added to model starting with the first
580 * element going to row 0, etc. This method will send a
581 * <code>tableChanged</code> notification message to all the listeners.
582 *
583 * @param columnName identifier of the newly created column
635 * @param row the row whose value is to be queried
636 * @param column the column whose value is to be queried
637 * @return true
638 * @see #setValueAt
639 */
640 public boolean isCellEditable(int row, int column) {
641 return true;
642 }
643
644 /**
645 * Returns an attribute value for the cell at <code>row</code>
646 * and <code>column</code>.
647 *
648 * @param row the row whose value is to be queried
649 * @param column the column whose value is to be queried
650 * @return the value Object at the specified cell
651 * @exception ArrayIndexOutOfBoundsException if an invalid row or
652 * column was given
653 */
654 public Object getValueAt(int row, int column) {
655 Vector<Object> rowVector = dataVector.elementAt(row);
656 return rowVector.elementAt(column);
657 }
658
659 /**
660 * Sets the object value for the cell at <code>column</code> and
661 * <code>row</code>. <code>aValue</code> is the new value. This method
662 * will generate a <code>tableChanged</code> notification.
663 *
664 * @param aValue the new value; this can be null
665 * @param row the row whose value is to be changed
666 * @param column the column whose value is to be changed
667 * @exception ArrayIndexOutOfBoundsException if an invalid row or
668 * column was given
669 */
670 public void setValueAt(Object aValue, int row, int column) {
671 Vector<Object> rowVector = dataVector.elementAt(row);
672 rowVector.setElementAt(aValue, column);
673 fireTableCellUpdated(row, column);
674 }
675
676 //
677 // Protected Methods
678 //
679
680 /**
681 * Returns a vector that contains the same objects as the array.
682 * @param anArray the array to be converted
683 * @return the new vector; if <code>anArray</code> is <code>null</code>,
684 * returns <code>null</code>
685 */
686 protected static Vector<Object> convertToVector(Object[] anArray) {
687 if (anArray == null) {
688 return null;
689 }
690 Vector<Object> v = new Vector<>(anArray.length);
691 for (Object o : anArray) {
692 v.addElement(o);
693 }
694 return v;
695 }
696
697 /**
698 * Returns a vector of vectors that contains the same objects as the array.
699 * @param anArray the double array to be converted
700 * @return the new vector of vectors; if <code>anArray</code> is
701 * <code>null</code>, returns <code>null</code>
702 */
703 protected static Vector<Vector<Object>> convertToVector(Object[][] anArray) {
704 if (anArray == null) {
705 return null;
706 }
707 Vector<Vector<Object>> v = new Vector<>(anArray.length);
708 for (Object[] o : anArray) {
709 v.addElement(convertToVector(o));
710 }
711 return v;
712 }
713
714 } // End of class DefaultTableModel
|