1 /*
2 * Scope: a generic MVC framework.
3 * Copyright (c) 2000-2002, The Scope team
4 * All rights reserved.
5 *
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * Neither the name "Scope" nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 *
36 * $Id: STableModel.java,v 1.12 2002/09/05 15:41:49 ludovicc Exp $
37 */
38 package org.scopemvc.view.swing;
39
40
41 import java.util.EventListener;
42 import javax.swing.JTable;
43 import javax.swing.event.ListDataListener;
44 import javax.swing.event.TableModelEvent;
45 import javax.swing.event.TableModelListener;
46 import javax.swing.table.TableModel;
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.scopemvc.core.PropertyManager;
50 import org.scopemvc.core.Selector;
51
52 /***
53 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A>
54 * @author <A HREF="mailto:daniel.michalik@autel.cz">Daniel Michalik</A>
55 * @created 05 September 2002
56 * @version $Revision: 1.12 $ $Date: 2002/09/05 15:41:49 $
57 * @see STable
58 */
59 public class STableModel extends SAbstractListModel
60 implements TableModel {
61
62 private final static Log LOG = LogFactory.getLog(STableModel.class);
63
64 /***
65 * TODO: describe of the Field
66 */
67 protected Selector[] columnSelectors;
68 /***
69 * TODO: describe of the Field
70 */
71 protected String[] columnNames;
72 /***
73 * if null editable when read-write property else read-only
74 */
75 protected boolean[] columnsEditable;
76 //
77
78 /***
79 * TODO: describe of the Field
80 */
81 protected PropertyManager manager;
82
83 /***
84 * TODO: describe of the Field
85 */
86 protected JTable table;
87
88
89 /***
90 * Constructor for the STableModel object
91 *
92 * @param inTable TODO: Describe the Parameter
93 */
94 public STableModel(JTable inTable) {
95 if (inTable == null) {
96 throw new IllegalArgumentException("Create model for a parent JTable, not null");
97 }
98 table = inTable;
99 }
100
101
102 // --------------------- implement TableModel ---------------------------
103
104 /***
105 * Gets the row count
106 *
107 * @return The rowCount value
108 */
109 public int getRowCount() {
110 if (LOG.isDebugEnabled()) {
111 LOG.debug("getRowCount: " + getSize());
112 }
113 return getSize();
114 }
115
116
117 /***
118 * Gets the column count
119 *
120 * @return The columnCount value
121 */
122 public int getColumnCount() {
123 if (columnSelectors == null) {
124 if (LOG.isDebugEnabled()) {
125 LOG.debug("getRowCount: 0");
126 }
127 return 0;
128 }
129 if (LOG.isDebugEnabled()) {
130 LOG.debug("getColumnCount: " + columnSelectors.length);
131 }
132 return columnSelectors.length;
133 }
134
135
136 /***
137 * Gets the column name
138 *
139 * @param inColumn TODO: Describe the Parameter
140 * @return The columnName value
141 */
142 public String getColumnName(int inColumn) {
143 if (columnNames == null || inColumn >= columnNames.length) {
144 return String.valueOf((char) ('A' + inColumn));
145 }
146 return columnNames[inColumn];
147 }
148
149
150 /***
151 * Gets the column class
152 *
153 * @param inColumn TODO: Describe the Parameter
154 * @return The columnClass value
155 */
156 public Class getColumnClass(int inColumn) {
157 PropertyManager manager = getManager();
158 Object row = getElementAt(0);
159 Selector selector = getColumnSelector(inColumn);
160 if (manager == null || row == null || selector == null) {
161 LOG.warn("getColumnClass: no manager or row or selector");
162 return Object.class;
163 }
164
165 try {
166 if (LOG.isDebugEnabled()) {
167 LOG.debug("getColumnClass: " + manager.getPropertyClass(row, selector));
168 }
169 return manager.getPropertyClass(row, selector);
170 } catch (Exception e) {
171 LOG.warn("getColumnClass: can't get class for " + inColumn, e);
172 }
173 return Object.class;
174 }
175
176
177 /***
178 * Gets the cell editable
179 *
180 * @param inRow TODO: Describe the Parameter
181 * @param inColumn TODO: Describe the Parameter
182 * @return The cellEditable value
183 */
184 public boolean isCellEditable(int inRow, int inColumn) {
185 if (columnsEditable != null && inColumn < columnsEditable.length) {
186 return columnsEditable[inColumn];
187 }
188
189 Object row = getElementAt(inRow);
190 PropertyManager manager = getManager();
191 Selector selector = getColumnSelector(inColumn);
192 if (manager == null || row == null || selector == null) {
193 LOG.warn("isCellEditable: no manager or row or selector");
194 return false;
195 }
196
197 try {
198 if (LOG.isDebugEnabled()) {
199 LOG.debug("isCellEditable: " + (!manager.isReadOnly(row, selector)));
200 }
201 return (!manager.isReadOnly(row, selector));
202 } catch (Exception ex) {
203 LOG.warn("isCellEditable(" + inRow + "," + inColumn + "): Unable "
204 + "to find out if cell is editable. Return false.", ex);
205 }
206 return false;
207 }
208
209
210 /***
211 * Gets the value at
212 *
213 * @param inRow TODO: Describe the Parameter
214 * @param inColumn TODO: Describe the Parameter
215 * @return The valueAt value
216 */
217 public Object getValueAt(int inRow, int inColumn) {
218 Object row = getElementAt(inRow);
219 Selector selector = getColumnSelector(inColumn);
220 PropertyManager manager = getPropertyManager();
221 if (manager == null || row == null || selector == null) {
222 LOG.warn("isCellEditable: no manager or row or selector");
223 return null;
224 }
225 try {
226 if (LOG.isDebugEnabled()) {
227 LOG.debug("getValueAt: " + manager.get(row, selector) + "(" + manager.get(row, selector).getClass() + ")");
228 }
229 return manager.get(row, selector);
230 } catch (Exception e) {
231 LOG.warn("Can't get column " + inColumn + " from row " + inRow, e);
232 }
233 return null;
234 }
235
236 /***
237 * Returns an array of all the listeners of the given type that were added
238 * to this model.
239 *
240 * @param listenerType TODO: Describe the Parameter
241 * @return The listeners value
242 * @returns all of the objects receiving <code>listenerType</code>
243 * notifications from this model
244 */
245 public EventListener[] getListeners(Class listenerType) {
246 return listenerList.getListeners(listenerType);
247 }
248
249
250 // ------------- public API -------------------
251
252 /***
253 * Sets the column selectors
254 *
255 * @param inSelectors The new columnSelectors value
256 */
257 public void setColumnSelectors(Selector[] inSelectors) {
258 columnSelectors = inSelectors;
259 }
260
261
262 /***
263 * Sets the column selector strings
264 *
265 * @param inSelectorStrings The new columnSelectorStrings value
266 */
267 public void setColumnSelectorStrings(String[] inSelectorStrings) {
268 if (inSelectorStrings == null) {
269 columnSelectors = null;
270 }
271 columnSelectors = new Selector[inSelectorStrings.length];
272 for (int i = 0; i < inSelectorStrings.length; i++) {
273 if (inSelectorStrings[i] == null) {
274 throw new IllegalArgumentException("Can't create column for null Selector");
275 }
276 columnSelectors[i] = Selector.fromString(inSelectorStrings[i]);
277 }
278 }
279
280
281 /***
282 * Sets the column names
283 *
284 * @param inNames The new columnNames value
285 */
286 public void setColumnNames(String[] inNames) {
287 columnNames = inNames;
288 }
289
290
291 /***
292 * Sets the editable columns
293 *
294 * @param inEditables The new editableColumns value
295 */
296 public void setEditableColumns(boolean[] inEditables) {
297 columnsEditable = inEditables;
298 }
299
300
301 /***
302 * Sets the value at
303 *
304 * @param inValue The new valueAt value
305 * @param inRow The new valueAt value
306 * @param inColumn The new valueAt value
307 */
308 public void setValueAt(Object inValue, int inRow, int inColumn) {
309 Object row = getElementAt(inRow);
310 Selector selector = getColumnSelector(inColumn);
311 PropertyManager manager = getPropertyManager();
312 if (manager == null || row == null || selector == null) {
313 LOG.warn("setValueAt: no manager or row or selector");
314 }
315 try {
316 manager.set(row, selector, inValue);
317 } catch (Exception e) {
318 LOG.warn("Can't set column " + inColumn + " from row " + inRow, e);
319 }
320 }
321
322
323 // ------ Override ListDataListener stuff to forward to TableModelListener ------
324
325 /***
326 * Adds an element to the ListDataListener attribute of the STableModel
327 * object
328 *
329 * @param l The element to be added to the ListDataListener attribute
330 */
331 public void addListDataListener(ListDataListener l) {
332 throw new UnsupportedOperationException("Can't add ListDataListener to STableModel");
333 }
334
335
336 /***
337 * TODO: document the method
338 *
339 * @param l TODO: Describe the Parameter
340 */
341 public void removeListDataListener(ListDataListener l) {
342 throw new UnsupportedOperationException("Can't remove ListDataListener from STableModel");
343 }
344
345
346 // ------- TableModelListeners copied from JDK1.3.1 AbstractTableModel -------
347
348 /***
349 * Adds a listener to the list that's notified each time a change to the
350 * data model occurs.
351 *
352 * @param l the TableModelListener
353 */
354 public void addTableModelListener(TableModelListener l) {
355 listenerList.add(TableModelListener.class, l);
356 }
357
358 /***
359 * Removes a listener from the list that's notified each time a change to
360 * the data model occurs.
361 *
362 * @param l the TableModelListener
363 */
364 public void removeTableModelListener(TableModelListener l) {
365 listenerList.remove(TableModelListener.class, l);
366 }
367
368 /***
369 * Notifies all listeners that all cell values in the table's rows may have
370 * changed. The number of rows may also have changed and the <code>JTable</code>
371 * should redraw the table from scratch. The structure of the table (as in
372 * the order of the columns) is assumed to be the same.
373 *
374 * @see TableModelEvent
375 */
376 public void fireTableDataChanged() {
377 fireTableChanged(new TableModelEvent(this));
378 }
379
380 /***
381 * Notifies all listeners that the table's structure has changed. The number
382 * of columns in the table, and the names and types of the new columns may
383 * be different from the previous state. If the <code>JTable</code> receives
384 * this event and its <code>autoCreateColumnsFromModel</code> flag is set it
385 * discards any table columns that it had and reallocates default columns in
386 * the order they appear in the model. This is the same as calling <code>setModel(TableModel)</code>
387 * on the <code>JTable</code>.
388 *
389 * @see TableModelEvent
390 */
391 public void fireTableStructureChanged() {
392 fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
393 }
394
395 /***
396 * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code>
397 * , inclusive, have been inserted.
398 *
399 * @param firstRow the first row
400 * @param lastRow the last row
401 * @see TableModelEvent
402 */
403 public void fireTableRowsInserted(int firstRow, int lastRow) {
404 fireTableChanged(
405 new TableModelEvent(
406 this,
407 firstRow,
408 lastRow,
409 TableModelEvent.ALL_COLUMNS,
410 TableModelEvent.INSERT));
411 }
412
413 /***
414 * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code>
415 * , inclusive, have been updated.
416 *
417 * @param firstRow the first row
418 * @param lastRow the last row
419 * @see TableModelEvent
420 */
421 public void fireTableRowsUpdated(int firstRow, int lastRow) {
422 fireTableChanged(
423 new TableModelEvent(
424 this,
425 firstRow,
426 lastRow,
427 TableModelEvent.ALL_COLUMNS,
428 TableModelEvent.UPDATE));
429 }
430
431 /***
432 * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code>
433 * , inclusive, have been deleted.
434 *
435 * @param firstRow the first row
436 * @param lastRow the last row
437 * @see TableModelEvent
438 */
439 public void fireTableRowsDeleted(int firstRow, int lastRow) {
440 fireTableChanged(
441 new TableModelEvent(
442 this,
443 firstRow,
444 lastRow,
445 TableModelEvent.ALL_COLUMNS,
446 TableModelEvent.DELETE));
447 }
448
449 /***
450 * Notifies all listeners that the value of the cell at <code>[row, column]</code>
451 * has been updated.
452 *
453 * @param row row of cell which has been updated
454 * @param column column of cell which has been updated
455 * @see TableModelEvent
456 */
457 public void fireTableCellUpdated(int row, int column) {
458 fireTableChanged(new TableModelEvent(this, row, row, column));
459 }
460
461 /***
462 * Forwards the given notification event to all <code>TableModelListeners</code>
463 * that registered themselves as listeners for this table model.
464 *
465 * @param e the event to be forwarded
466 * @see #addTableModelListener
467 * @see TableModelEvent
468 */
469 public void fireTableChanged(TableModelEvent e) {
470 // Guaranteed to return a non-null array
471 Object[] listeners = listenerList.getListenerList();
472 // Process the listeners last to first, notifying
473 // those that are interested in this event
474 for (int i = listeners.length - 2; i >= 0; i -= 2) {
475 if (listeners[i] == TableModelListener.class) {
476 ((TableModelListener) listeners[i + 1]).tableChanged(e);
477 }
478 }
479 }
480
481
482 // -------------- internal -----------------
483
484 /***
485 * Gets the column selector
486 *
487 * @param inColumn TODO: Describe the Parameter
488 * @return The columnSelector value
489 */
490 protected Selector getColumnSelector(int inColumn) {
491 if (columnSelectors == null) {
492 return null;
493 }
494 return columnSelectors[inColumn];
495 }
496
497
498 /***
499 * Gets the property manager
500 *
501 * @return The propertyManager value
502 */
503 protected PropertyManager getPropertyManager() {
504 if (manager != null) {
505 return manager;
506 }
507
508 if (getRowCount() < 1) {
509 return null;
510 }
511
512 Object row = getElementAt(0);
513 manager = PropertyManager.getInstance(row);
514 return manager;
515 }
516
517
518 // ---------------- Bound model stuff ------------------
519
520 /***
521 * Called internally from updateFromProperty().
522 *
523 * @param inModel The new shownModel value
524 */
525 protected void setShownModel(Object inModel) {
526
527 super.setShownModel(inModel);
528
529 // if (table instanceof STable) {
530 // ((STable)table).createDefaultColumnsFromModel();
531 // }
532
533 // ***** This is necessary for updates to work at all...
534 // ... but it looks very wrong.
535 fireTableDataChanged();
536
537 manager = null;
538
539 // ***** This is broken because of the above hack
540 if (table instanceof STable) {
541 ((STable) table).refreshSelection();
542 } else {
543 // Could use a better strategy for completeness
544 table.clearSelection();
545 }
546 }
547
548
549 /***
550 * TODO: document the method
551 *
552 * @param source TODO: Describe the Parameter
553 * @param index0 TODO: Describe the Parameter
554 * @param index1 TODO: Describe the Parameter
555 */
556 protected void fireContentsChanged(Object source, int index0, int index1) {
557 fireTableRowsUpdated(index0, index1);
558 }
559
560
561 /***
562 * TODO: document the method
563 *
564 * @param source TODO: Describe the Parameter
565 * @param index0 TODO: Describe the Parameter
566 * @param index1 TODO: Describe the Parameter
567 */
568 protected void fireIntervalAdded(Object source, int index0, int index1) {
569 fireTableRowsInserted(index0, index1);
570 }
571
572
573 /***
574 * TODO: document the method
575 *
576 * @param source TODO: Describe the Parameter
577 * @param index0 TODO: Describe the Parameter
578 * @param index1 TODO: Describe the Parameter
579 */
580 protected void fireIntervalRemoved(Object source, int index0, int index1) {
581 fireTableRowsDeleted(index0, index1);
582 }
583 }
This page was automatically generated by Maven