KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > admin > common > XObjectTableModel


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.admin.common;
5
6 import java.lang.reflect.Method JavaDoc;
7 import java.util.ArrayList JavaDoc;
8 import java.util.Collection JavaDoc;
9 import java.util.Enumeration JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.Iterator JavaDoc;
12
13 import javax.swing.SwingConstants JavaDoc;
14 import javax.swing.table.AbstractTableModel JavaDoc;
15
16 /**
17  * ObjectTableModel - abstract view onto a collection of Objects of the same
18  * type.
19  *
20  * You tell it the type, the display field names, and the object set. The
21  * ordering of the list elements will be determined by the type of object
22  * collection used to create the instance.
23  * The "field" names are used to determine a getter method. Foo -> getFoo.
24  *
25  * When used in combintaion with a Table, this facility is meant to provide
26  * a high-level data display/editing view with very low cognitive overhead
27  * and high usability.
28  */

29
30 public class XObjectTableModel extends AbstractTableModel JavaDoc {
31   private Class JavaDoc
32     m_type;
33
34   private ArrayList JavaDoc
35     m_fieldDescriptions;
36   
37   private ArrayList JavaDoc
38     m_objects = new ArrayList JavaDoc();
39
40   private String JavaDoc[]
41     m_fieldNames;
42   
43   private ArrayList JavaDoc
44     m_showingFields;
45
46   protected static final HashMap JavaDoc
47     m_primitiveMap = new HashMap JavaDoc();
48
49   static {
50     m_primitiveMap.put(Double.TYPE, Double JavaDoc.class);
51     m_primitiveMap.put(Integer.TYPE, Integer JavaDoc.class);
52     m_primitiveMap.put(Boolean.TYPE, Boolean JavaDoc.class);
53     m_primitiveMap.put(Character.TYPE, Character JavaDoc.class);
54     m_primitiveMap.put(Byte.TYPE, Byte JavaDoc.class);
55     m_primitiveMap.put(Float.TYPE, Float JavaDoc.class);
56     m_primitiveMap.put(Long.TYPE, Long JavaDoc.class);
57   }
58     
59   public static final int UP = SwingConstants.NORTH;
60   public static final int DOWN = SwingConstants.SOUTH;
61
62   public XObjectTableModel() {
63     super();
64   }
65
66   public XObjectTableModel(Class JavaDoc type, String JavaDoc[] fields, String JavaDoc[] headings) {
67     super();
68
69     m_type = type;
70     m_fieldNames = fields;
71     
72     createColumns(fields, headings);
73   }
74
75   public XObjectTableModel(
76     Class JavaDoc type,
77     String JavaDoc[] fields,
78     String JavaDoc[] headings,
79     Object JavaDoc[] data)
80   {
81     this(type, fields, headings);
82
83     if(data != null) {
84       add(data);
85     }
86   }
87
88   public XObjectTableModel(
89     Class JavaDoc type,
90     String JavaDoc[] fields,
91     String JavaDoc[] headings,
92     Enumeration JavaDoc enumeration)
93 {
94     this(type, fields, headings);
95
96     if(enumeration != null) {
97       add(enumeration);
98     }
99   }
100
101   public XObjectTableModel(
102     Class JavaDoc type,
103     String JavaDoc[] fields,
104     String JavaDoc[] headings,
105     Iterator JavaDoc iter)
106   {
107     this(type, fields, headings);
108
109     if(iter != null) {
110       add(iter);
111     }
112   }
113
114   public XObjectTableModel(
115     Class JavaDoc type,
116     String JavaDoc[] fields,
117     String JavaDoc[] headings,
118     Collection JavaDoc c)
119   {
120     this(type, fields, headings, c.iterator());
121   }
122
123   private void determineMethods(FieldDescription fieldDesc) {
124     String JavaDoc name = fieldDesc.getFieldName();
125     Method JavaDoc[] methods = m_type.getMethods();
126     Method JavaDoc method;
127     String JavaDoc methodName;
128     Class JavaDoc returnType;
129     Class JavaDoc[] paramTypes;
130
131     for(int i = 0; i < methods.length; i++) {
132       method = methods[i];
133       returnType = method.getReturnType();
134       paramTypes = method.getParameterTypes();
135       methodName = method.getName();
136
137       if(("set"+name).equals(methodName) &&
138          paramTypes.length == 1 &&
139          (paramTypes[0].isPrimitive() ||
140           paramTypes[0].equals(String JavaDoc.class) ||
141           paramTypes[0].equals(java.util.Date JavaDoc.class) ||
142           hasEditor(paramTypes[0])))
143       {
144         fieldDesc.setSetter(method);
145         break;
146       }
147     }
148
149     for(int i = 0; i < methods.length; i++) {
150       method = methods[i];
151       returnType = method.getReturnType();
152       paramTypes = method.getParameterTypes();
153       methodName = method.getName();
154
155       if((("get"+name).equals(methodName) ||
156           ("is"+name).equals(methodName)) &&
157           paramTypes.length == 0 &&
158           (canHandle(returnType) || hasEditor(returnType)))
159       {
160         fieldDesc.setGetter(method);
161         fieldDesc.setSortable(determineSortability(method));
162         break;
163       }
164     }
165
166     for(int i = 0; i < methods.length; i++) {
167       method = methods[i];
168       methodName = method.getName();
169
170       if(name.equals(methodName)) {
171         fieldDesc.setOperation(method);
172         break;
173       }
174     }
175   }
176
177   private static boolean canHandle(Class JavaDoc c) {
178     try {
179       return c.isPrimitive() ||
180              c.equals(String JavaDoc.class) ||
181              c.equals(java.util.Date JavaDoc.class) ||
182              c.getField("TYPE") != null;
183     } catch(NoSuchFieldException JavaDoc e) {/**/}
184     return false;
185   }
186   
187   private boolean determineSortability(Method JavaDoc getter) {
188     if(getter != null) {
189       Class JavaDoc type = getter.getReturnType();
190
191       return Comparable JavaDoc.class.isAssignableFrom(type) ||
192         (type.isPrimitive() && !Void JavaDoc.class.equals(type));
193     }
194
195     return false;
196   }
197
198   public void createColumns(String JavaDoc[] fields, String JavaDoc[] headings) {
199     if(m_type != null) {
200       FieldDescription fieldDesc;
201
202       m_fieldDescriptions = new ArrayList JavaDoc();
203       m_showingFields = new ArrayList JavaDoc();
204
205       for(int i = 0; i < m_fieldNames.length; i++) {
206         fieldDesc = new FieldDescription(fields[i], headings[i]);
207         m_fieldDescriptions.add(fieldDesc);
208         m_showingFields.add(fieldDesc);
209         determineMethods(fieldDesc);
210       }
211     }
212   }
213
214   public int getShowingFieldCount() {
215     return getColumnCount();
216   }
217   
218   public String JavaDoc[] getShowingFields() {
219     String JavaDoc[] fieldNames = new String JavaDoc[getShowingFieldCount()];
220
221     for(int i = 0; i < fieldNames.length; i++) {
222       fieldNames[i] = getShowingFieldDescription(i).getFieldName();
223     }
224     
225     return fieldNames;
226   }
227   
228   public FieldDescription getFieldDescription(int index) {
229     return (FieldDescription)m_fieldDescriptions.get(index);
230   }
231   
232   public FieldDescription getFieldDescription(String JavaDoc fieldName) {
233     return getFieldDescription(indexOfField(fieldName));
234   }
235   
236   public FieldDescription getShowingFieldDescription(int index) {
237     return (FieldDescription)m_showingFields.get(index);
238   }
239   
240   public FieldDescription getShowingFieldDescription(String JavaDoc fieldName) {
241     int size = m_showingFields.size();
242     FieldDescription fieldDesc;
243     
244     for(int i = 0; i < size; i++) {
245       fieldDesc = getShowingFieldDescription(i);
246       
247       if(fieldName.equals(fieldDesc.getFieldName())) {
248         return fieldDesc;
249       }
250     }
251
252     return null;
253   }
254   
255   private Class JavaDoc _mapPrimitive(Class JavaDoc c) {
256     return (Class JavaDoc)m_primitiveMap.get(c);
257   }
258
259   public boolean isColumnSortable(int col) {
260     return getFieldDescription(col).isSortable();
261   }
262
263   public Method JavaDoc getFieldGetter(int col) {
264     return getFieldDescription(col).getGetter();
265   }
266   
267   public Method JavaDoc getShowingFieldGetter(int col) {
268     return getShowingFieldDescription(col).getGetter();
269   }
270
271   public Method JavaDoc getFieldSetter(int col) {
272     return getFieldDescription(col).getSetter();
273   }
274
275   public Method JavaDoc getShowingFieldSetter(int col) {
276     return getShowingFieldDescription(col).getSetter();
277   }
278
279   public Method JavaDoc getFieldOperation(int col) {
280     return getFieldDescription(col).getOperation();
281   }
282
283   public Method JavaDoc getShowingFieldOperation(int col) {
284     return getShowingFieldDescription(col).getOperation();
285   }
286
287   public Class JavaDoc getColumnClass(int col) {
288     Method JavaDoc method = getShowingFieldGetter(col);
289
290     if(method != null) {
291       Class JavaDoc colClass = method.getReturnType();
292
293       if(colClass.isPrimitive()) {
294         colClass = _mapPrimitive(colClass);
295       }
296
297       return colClass;
298     }
299
300     if((method = getShowingFieldOperation(col)) != null) {
301       return Method JavaDoc.class;
302     }
303
304     return Object JavaDoc.class;
305   }
306
307   public void clear() {
308     m_objects.clear();
309   }
310
311   public void add(Object JavaDoc object) {
312     if(m_type != null) {
313       m_objects.add(object);
314     }
315   }
316
317   public void add(int index, Object JavaDoc object) {
318     if(m_type != null) {
319       m_objects.add(index, object);
320     }
321   }
322
323   public void remove(Object JavaDoc object) {
324     if(m_type != null) {
325       m_objects.remove(object);
326     }
327   }
328
329   public void remove(int index) {
330     if(m_type != null) {
331       m_objects.remove(index);
332     }
333   }
334
335   public void add(Object JavaDoc[] objects) {
336     if(objects != null) {
337       for(int i = 0; i < objects.length; i++) {
338         add(objects[i]);
339       }
340     }
341   }
342
343   public void remove(Object JavaDoc[] objects) {
344     if(objects != null) {
345       for(int i = 0; i < objects.length; i++) {
346         remove(objects[i]);
347       }
348     }
349   }
350
351   public void set(Object JavaDoc[] objects) {
352     clear();
353     add(objects);
354     fireTableDataChanged();
355   }
356
357   public void add(Enumeration JavaDoc enumeration) {
358     if(enumeration != null) {
359       while(enumeration.hasMoreElements()) {
360         add(enumeration.nextElement());
361       }
362     }
363   }
364
365   public void set(Enumeration JavaDoc enumeration) {
366     clear();
367     add(enumeration);
368     fireTableDataChanged();
369   }
370
371   public void add(Iterator JavaDoc iter) {
372     if(iter != null) {
373       while(iter.hasNext()) {
374         add(iter.next());
375       }
376     }
377   }
378
379   public void set(Iterator JavaDoc iter) {
380     clear();
381     add(iter);
382     fireTableDataChanged();
383   }
384
385   public void add(Collection JavaDoc collection) {
386     if(collection != null) {
387       add(collection.iterator());
388     }
389   }
390
391   public void set(Collection JavaDoc collection) {
392     clear();
393     add(collection);
394     fireTableDataChanged();
395   }
396
397   public int getRowCount() {
398     return m_objects != null ? m_objects.size() : 0;
399   }
400
401   public int getColumnCount() {
402     return m_showingFields != null ? m_showingFields.size() : 0;
403   }
404
405   public boolean isCellEditable(int row, int col) {
406     return getShowingFieldSetter(col) != null ||
407            getShowingFieldOperation(col) != null;
408   }
409
410   public String JavaDoc getColumnName(int col) {
411     FieldDescription fieldDesc = getShowingFieldDescription(col);
412     String JavaDoc heading = fieldDesc.getHeader();
413     
414     return heading != null ? heading : fieldDesc.getFieldName();
415   }
416
417   public String JavaDoc getFieldName(int col) {
418     FieldDescription fieldDesc = getShowingFieldDescription(col);
419     return fieldDesc != null ? fieldDesc.getFieldName() : null;
420   }
421
422   public Object JavaDoc getObjectAt(int row) {
423     return m_objects.get(row);
424   }
425
426   public int getObjectIndex(Object JavaDoc object) {
427     int count = getRowCount();
428
429     for(int i = 0; i < count; i++) {
430       if(object == getObjectAt(i)) {
431         return i;
432       }
433     }
434
435     return -1;
436   }
437
438   public Object JavaDoc getValueAt(int row, int col) {
439     Method JavaDoc method = getShowingFieldGetter(col);
440
441     if(method != null) {
442       try {
443         return method.invoke(getObjectAt(row), new Object JavaDoc[] {});
444       }
445       catch(Exception JavaDoc e) {
446         return e.getMessage();
447       }
448     }
449
450     if((method = getShowingFieldOperation(col)) != null) {
451       return method;
452     }
453
454     return "";
455   }
456
457   protected Object JavaDoc xgetValueAt(int row, int col) {
458     Method JavaDoc method = getFieldGetter(col);
459
460     if(method != null) {
461       try {
462         return method.invoke(getObjectAt(row), new Object JavaDoc[] {});
463       }
464       catch(Exception JavaDoc e) {
465         return e.getMessage();
466       }
467     }
468
469     if((method = getFieldOperation(col)) != null) {
470       return method;
471     }
472
473     return "";
474   }
475
476   public void setValueAt(Object JavaDoc value, int row, int col) {
477     Method JavaDoc setter = getShowingFieldSetter(col);
478
479     if(setter != null) {
480       try {
481         setter.invoke(getObjectAt(row), new Object JavaDoc[] {value});
482         fireTableCellUpdated(row, col);
483       }
484       catch(Exception JavaDoc e) {/*ignore*/}
485     }
486   }
487
488   private boolean compareAdjacentRows(int direction, int row, int col) {
489     Comparable JavaDoc prev = (Comparable JavaDoc)xgetValueAt(row-1, col);
490     Object JavaDoc next = xgetValueAt(row, col);
491     int diff = prev.compareTo(next);
492     
493     return (direction == DOWN) ? (diff > 0) : (diff < 0);
494   }
495
496   public void sortColumn(int col, int direction) {
497     int count = getRowCount();
498
499     for(int i = 0; i < count; i++) {
500       for(int j = i; j > 0 && compareAdjacentRows(direction, j, col); j--) {
501         Object JavaDoc tmp = getObjectAt(j);
502
503         m_objects.set(j, getObjectAt(j-1));
504         m_objects.set(j-1, tmp);
505       }
506     }
507
508     fireTableDataChanged();
509   }
510
511   public boolean hasEditor(Class JavaDoc type) {
512     return false;
513   }
514
515   public int indexOfField(String JavaDoc fieldName) {
516     if(fieldName != null) {
517       for(int i = 0; i < m_fieldNames.length; i++) {
518         if(fieldName.equals(m_fieldNames[i])) {
519           return i;
520         }
521       }
522     }
523
524     return -1;
525   }
526
527   protected FieldDescription findDescription(String JavaDoc fieldName) {
528     int size = m_fieldDescriptions.size();
529     FieldDescription fieldDesc;
530     
531     for(int i = 0; i < size; i++) {
532       fieldDesc = getFieldDescription(i);
533       if(fieldName.equals(fieldDesc.getFieldName())) {
534         return fieldDesc;
535       }
536     }
537     
538     return null;
539   }
540   
541   public void showColumnsExclusive(String JavaDoc[] fieldNames) {
542     FieldDescription fieldDesc;
543     
544     m_showingFields = new ArrayList JavaDoc();
545     for(int i = 0; i < fieldNames.length; i++) {
546       if((fieldDesc = findDescription(fieldNames[i])) != null) {
547         m_showingFields.add(fieldDesc);
548       }
549     }
550
551     fireTableStructureChanged();
552   }
553   
554   public void showColumn(String JavaDoc fieldName) {
555     if(isColumnShowing(fieldName)) {
556       return;
557     }
558     
559     int showingCount = m_showingFields.size();
560     int fieldIndex = indexOfField(fieldName);
561     FieldDescription targetDesc = getFieldDescription(fieldIndex);
562     FieldDescription fieldDesc;
563     int shownIndex;
564    
565     for(int i = 0; i < showingCount; i++) {
566       fieldDesc = getShowingFieldDescription(i);
567       shownIndex = fieldDesc.indexOfField();
568       
569       if(fieldIndex <= shownIndex) {
570         m_showingFields.add(i, targetDesc);
571         fireTableStructureChanged();
572         return;
573       }
574     }
575
576     m_showingFields.add(targetDesc);
577     fireTableStructureChanged();
578   }
579   
580   public void hideColumn(String JavaDoc fieldName) {
581     int index = getShowingFieldIndex(fieldName);
582
583     if(index != -1) {
584       m_showingFields.remove(index);
585       fireTableStructureChanged();
586     }
587   }
588   
589   public boolean isColumnShowing(String JavaDoc fieldName) {
590     int size = m_showingFields.size();
591     FieldDescription fieldDesc;
592     
593     for(int i = 0; i < size; i++) {
594       fieldDesc = getShowingFieldDescription(i);
595       
596       if(fieldName.equals(fieldDesc.getFieldName())) {
597         return true;
598       }
599     }
600
601     return false;
602   }
603   
604   public int getShowingFieldIndex(String JavaDoc fieldName) {
605     int size = m_showingFields.size();
606     FieldDescription fieldDesc;
607     
608     for(int i = 0; i < size; i++) {
609       fieldDesc = getShowingFieldDescription(i);
610       
611       if(fieldName.equals(fieldDesc.getFieldName())) {
612         return i;
613       }
614     }
615
616     return -1;
617   }
618   
619   class FieldDescription {
620     String JavaDoc m_fieldName;
621     String JavaDoc m_header;
622     Method JavaDoc m_getter;
623     Method JavaDoc m_setter;
624     Method JavaDoc m_op;
625     boolean m_sortable;
626    
627     FieldDescription(String JavaDoc fieldName, String JavaDoc header) {
628       m_fieldName = fieldName;
629       m_header = header;
630     }
631
632     String JavaDoc getFieldName() {
633       return m_fieldName;
634     }
635     
636     int indexOfField() {
637       return XObjectTableModel.this.indexOfField(m_fieldName);
638     }
639     
640     String JavaDoc getHeader() {
641       return m_header != null ? m_header : m_fieldName;
642     }
643
644     void setGetter(Method JavaDoc getter) {
645       m_getter = getter;
646     }
647     
648     Method JavaDoc getGetter() {
649       return m_getter;
650     }
651     
652     void setSetter(Method JavaDoc setter) {
653       m_setter = setter;
654     }
655     
656     Method JavaDoc getSetter() {
657       return m_setter;
658     }
659     
660     void setOperation(Method JavaDoc op) {
661       m_op = op;
662     }
663     
664     Method JavaDoc getOperation() {
665       return m_op;
666     }
667     
668     void setSortable(boolean sortable) {
669       m_sortable = sortable;
670     }
671     
672     boolean isSortable() {
673       return m_sortable;
674     }
675   }
676 }
677
Popular Tags