KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > data > column > AbstractColumn


1 package prefuse.data.column;
2
3 import java.util.Date JavaDoc;
4
5 import prefuse.data.DataTypeException;
6 import prefuse.data.event.ColumnListener;
7 import prefuse.data.parser.DataParseException;
8 import prefuse.data.parser.DataParser;
9 import prefuse.data.parser.ObjectParser;
10 import prefuse.data.parser.ParserFactory;
11 import prefuse.util.TypeLib;
12 import prefuse.util.collections.CopyOnWriteArrayList;
13
14 /**
15  * Abstract base class for Column implementations. Provides listener support
16  * and default implementations of column methods.
17  *
18  * @author <a HREF="http://jheer.org">jeffrey heer</a>
19  */

20 public abstract class AbstractColumn implements Column {
21
22     protected final Class JavaDoc m_columnType;
23     protected DataParser m_parser;
24     protected Object JavaDoc m_defaultValue;
25     protected boolean m_readOnly;
26     
27     protected CopyOnWriteArrayList m_listeners;
28     
29     /**
30      * Create a new AbstractColumn of type Object.
31      */

32     public AbstractColumn() {
33         this(Object JavaDoc.class, null);
34     }
35
36     /**
37      * Create a new AbstractColumn of a given type.
38      * @param columnType the data type stored by this column
39      */

40     public AbstractColumn(Class JavaDoc columnType) {
41         this(columnType, null);
42     }
43
44     /**
45      * Create a new AbstractColumn of a given type.
46      * @param columnType the data type stored by this column
47      * @param defaultValue the default data value to use
48      */

49     public AbstractColumn(Class JavaDoc columnType, Object JavaDoc defaultValue) {
50         m_columnType = columnType;
51         
52         DataParser p = ParserFactory.getDefaultFactory().getParser(columnType);
53         m_parser = ( p==null ? new ObjectParser() : p );
54         
55         setDefaultValue(defaultValue);
56         m_readOnly = false;
57         m_listeners = new CopyOnWriteArrayList();
58     }
59     
60     // ------------------------------------------------------------------------
61
// Column Metadata
62

63     /**
64      * Indicates if the values in this column are read-only.
65      * @return true if the values can not be edited, false otherwise
66      */

67     public boolean isReadOnly() {
68         return m_readOnly;
69     }
70     
71     /**
72      * Sets if the values in this column are read-only
73      * @param readOnly true to ensure the values can not be edited,
74      * false otherwise
75      */

76     public void setReadOnly(boolean readOnly) {
77         m_readOnly = readOnly;
78     } //
79

80     /**
81      * Indicates if the value at the given row can be edited.
82      * @param row the row to check
83      * @return true is the value can be modified, false otherwise
84      */

85     public boolean isCellEditable(int row) {
86         return !m_readOnly;
87     }
88     
89     /**
90      * Returns the most specific superclass for the values in the column
91      * @return the Class of the column's data values
92      */

93     public Class JavaDoc getColumnType() {
94         return m_columnType;
95     }
96     
97     /**
98      * @see prefuse.data.column.Column#getParser()
99      */

100     public DataParser getParser() {
101         return m_parser;
102     }
103     
104     /**
105      * @see prefuse.data.column.Column#setParser(prefuse.data.parser.DataParser)
106      */

107     public void setParser(DataParser parser) {
108         if ( !m_columnType.isAssignableFrom(parser.getType()) ) {
109             throw new IllegalArgumentException JavaDoc(
110                "Parser type ("+parser.getType().getName()+") incompatible with"
111                +" this column's data type ("+m_columnType.getName()+")");
112         }
113         m_parser = parser;
114     }
115     
116     // ------------------------------------------------------------------------
117
// Listener Methods
118

119     /**
120      * Adds a listener to be notified when this column changes
121      * @param listener the ColumnListener to add
122      */

123     public void addColumnListener(ColumnListener listener) {
124         m_listeners.add(listener);
125     }
126
127     /**
128      * Removes a listener, causing it to no longer be notified of changes
129      * @param listener the ColumnListener to remove
130      */

131     public void removeColumnListener(ColumnListener listener) {
132         m_listeners.remove(listener);
133     }
134     
135     /**
136      * Notifies all registered listeners of a column UPDATE event
137      */

138     protected final void fireColumnEvent(int type, int start, int end) {
139         Object JavaDoc[] lstnrs = m_listeners.getArray();
140         for ( int i=0; i<lstnrs.length; ++i )
141             ((ColumnListener)lstnrs[i]).columnChanged(this, type, start, end);
142     }
143     
144     /**
145      * Notifies all registered listeners of a column UPDATE event
146      * @param idx the row index of the column that was updated
147      * @param prev the previous value at the given index
148      */

149     protected final void fireColumnEvent(int idx, int prev) {
150         Object JavaDoc[] lstnrs = m_listeners.getArray();
151         for ( int i=0; i<lstnrs.length; ++i )
152             ((ColumnListener)lstnrs[i]).columnChanged(this, idx, prev);
153     }
154     
155     /**
156      * Notifies all registered listeners of a column UPDATE event
157      * @param idx the row index of the column that was updated
158      * @param prev the previous value at the given index
159      */

160     protected final void fireColumnEvent(int idx, long prev) {
161         Object JavaDoc[] lstnrs = m_listeners.getArray();
162         for ( int i=0; i<lstnrs.length; ++i )
163             ((ColumnListener)lstnrs[i]).columnChanged(this, idx, prev);
164     }
165     
166     /**
167      * Notifies all registered listeners of a column UPDATE event
168      * @param idx the row index of the column that was updated
169      * @param prev the previous value at the given index
170      */

171     protected final void fireColumnEvent(int idx, float prev) {
172         Object JavaDoc[] lstnrs = m_listeners.getArray();
173         for ( int i=0; i<lstnrs.length; ++i )
174             ((ColumnListener)lstnrs[i]).columnChanged(this, idx, prev);
175     }
176     
177     /**
178      * Notifies all registered listeners of a column UPDATE event
179      * @param idx the row index of the column that was updated
180      * @param prev the previous value at the given index
181      */

182     protected final void fireColumnEvent(int idx, double prev) {
183         Object JavaDoc[] lstnrs = m_listeners.getArray();
184         for ( int i=0; i<lstnrs.length; ++i )
185             ((ColumnListener)lstnrs[i]).columnChanged(this, idx, prev);
186     }
187     
188     /**
189      * Notifies all registered listeners of a column UPDATE event
190      * @param idx the row index of the column that was updated
191      * @param prev the previous value at the given index
192      */

193     protected final void fireColumnEvent(int idx, boolean prev) {
194         Object JavaDoc[] lstnrs = m_listeners.getArray();
195         for ( int i=0; i<lstnrs.length; ++i )
196             ((ColumnListener)lstnrs[i]).columnChanged(this, idx, prev);
197     }
198     
199     /**
200      * Notifies all registered listeners of a column UPDATE event
201      * @param idx the row index of the column that was updated
202      * @param prev the previous value at the given index
203      */

204     protected final void fireColumnEvent(int idx, Object JavaDoc prev) {
205         Object JavaDoc[] lstnrs = m_listeners.getArray();
206         for ( int i=0; i<lstnrs.length; ++i )
207             ((ColumnListener)lstnrs[i]).columnChanged(this, idx, prev);
208     }
209     
210     // ------------------------------------------------------------------------
211
// Data Access Methods
212

213     /**
214      * Returns the default value for rows that have not been set explicitly.
215      */

216     public Object JavaDoc getDefaultValue() {
217         return m_defaultValue;
218     }
219  
220     /**
221      * Sets the default value for this column. Rows previously added
222      * under a different default value will not be changed as a result
223      * of this method; the new default will apply to newly added rows
224      * only.
225      * @param dflt
226      */

227     public void setDefaultValue(Object JavaDoc dflt) {
228         boolean prim = m_columnType.isPrimitive();
229         if ( dflt != null &&
230             ((!prim && !m_columnType.isInstance(dflt)) ||
231              (prim && !TypeLib.isWrapperInstance(m_columnType, dflt))) )
232         {
233             throw new IllegalArgumentException JavaDoc(
234                 "Default value is not of type " + m_columnType.getName());
235         }
236         m_defaultValue = dflt;
237     }
238     
239     /**
240      * Reverts the specified row back to the column's default value.
241      * @param row
242      */

243     public void revertToDefault(int row) {
244         set(m_defaultValue, row);
245     }
246     
247     /**
248      * Indicates if the get method can be called without
249      * an exception being thrown for the given type.
250      * @param type the Class of the data type to check
251      * @return true if the type is supported by this column, false otherwise
252      */

253     public boolean canGet(Class JavaDoc type) {
254         if ( type == null ) return false;
255         
256         if ( m_columnType.isPrimitive() ) {
257             boolean primTypes = type.isAssignableFrom(m_columnType) ||
258                     (TypeLib.isNumericType(m_columnType)
259                      && TypeLib.isNumericType(type));
260              
261             return primTypes
262                 || type.isAssignableFrom(TypeLib.getWrapperType(m_columnType))
263                 || type.isAssignableFrom(String JavaDoc.class);
264         } else {
265             return type.isAssignableFrom(m_columnType);
266         }
267     }
268     
269     /**
270      * Indicates if the set method can be called without
271      * an exception being thrown for the given type.
272      * @param type the Class of the data type to check
273      * @return true if the type is supported by this column, false otherwise
274      */

275     public boolean canSet(Class JavaDoc type) {
276         if ( type == null ) return false;
277         
278         if ( m_columnType.isPrimitive() ) {
279             return m_columnType.isAssignableFrom(type)
280                 || TypeLib.getWrapperType(m_columnType).isAssignableFrom(type)
281                 || String JavaDoc.class.isAssignableFrom(type);
282         } else {
283             return m_columnType.isAssignableFrom(type);
284         }
285     }
286     
287     // ------------------------------------------------------------------------
288
// Data Type Convenience Methods
289

290     // because java's type system can be tedious at times...
291

292     // -- int -----------------------------------------------------------------
293

294     /**
295      * Indicates if convenience get method can be called without
296      * an exception being thrown for the int type.
297      * @return true if getInt is supported, false otherwise
298      */

299     public boolean canGetInt() {
300         return canGet(int.class);
301     }
302     
303     /**
304      * Indicates if convenience set method can be called without
305      * an exception being thrown for the int type.
306      * @return true if setInt is supported, false otherwise
307      */

308     public boolean canSetInt() {
309         return canSet(int.class);
310     }
311     
312     /**
313      * Get the data value at the specified row as an integer
314      * @param row the row from which to retrieve the value
315      * @return the data value as an integer
316      * @throws DataTypeException if this column does not
317      * support the integer type
318      */

319     public int getInt(int row) throws DataTypeException {
320         if ( canGetInt() ) {
321             return ((Integer JavaDoc)get(row)).intValue();
322         } else {
323             throw new DataTypeException(int.class);
324         }
325     }
326     
327     /**
328      * Set the data value at the specified row as an integer
329      * @param val the value to set
330      * @param row the row at which to set the value
331      * @throws DataTypeException if this column does not
332      * support the integer type
333      */

334     public void setInt(int val, int row) throws DataTypeException {
335         if ( canSetInt() ) {
336             set(new Integer JavaDoc(val), row);
337         } else {
338             throw new DataTypeException(int.class);
339         }
340     }
341
342     // -- long ----------------------------------------------------------------
343

344     /**
345      * Indicates if convenience get method can be called without
346      * an exception being thrown for the long type.
347      * @return true if getLong is supported, false otherwise
348      */

349     public boolean canGetLong() {
350         return canGet(long.class);
351     }
352     
353     /**
354      * Indicates if convenience set method can be called without
355      * an exception being thrown for the long type.
356      * @return true if setLong is supported, false otherwise
357      */

358     public boolean canSetLong() {
359         return canSet(long.class);
360     }
361     
362     /**
363      * Get the data value at the specified row as a long
364      * @param row the row from which to retrieve the value
365      * @return the data value as a long
366      * @throws DataTypeException if this column does not
367      * support the long type
368      */

369     public long getLong(int row) throws DataTypeException {
370         if ( canGetLong() ) {
371             return ((Long JavaDoc)get(row)).longValue();
372         } else {
373             throw new DataTypeException(long.class);
374         }
375     }
376     
377     /**
378      * Set the data value at the specified row as a long
379      * @param val the value to set
380      * @param row the row at which to set the value
381      * @throws DataTypeException if this column does not
382      * support the long type
383      */

384     public void setLong(long val, int row) throws DataTypeException {
385         if ( canSetLong() ) {
386             set(new Long JavaDoc(val), row);
387         } else {
388             throw new DataTypeException(long.class);
389         }
390     }
391     
392     // -- float ---------------------------------------------------------------
393

394     /**
395      * Indicates if convenience get method can be called without
396      * an exception being thrown for the float type.
397      * @return true if getFloat is supported, false otherwise
398      */

399     public boolean canGetFloat() {
400         return canGet(float.class);
401     }
402     
403     /**
404      * Indicates if convenience set method can be called without
405      * an exception being thrown for the float type.
406      * @return true if setFloat is supported, false otherwise
407      */

408     public boolean canSetFloat() {
409         return canSet(float.class);
410     }
411     
412     /**
413      * Get the data value at the specified row as a float
414      * @param row the row from which to retrieve the value
415      * @return the data value as a float
416      * @throws DataTypeException if this column does not
417      * support the float type
418      */

419     public float getFloat(int row) throws DataTypeException {
420         if ( canGetFloat() ) {
421             return ((Float JavaDoc)get(row)).floatValue();
422         } else {
423             throw new DataTypeException(float.class);
424         }
425     }
426     
427     /**
428      * Set the data value at the specified row as a float
429      * @param val the value to set
430      * @param row the row at which to set the value
431      * @throws DataTypeException if this column does not
432      * support the float type
433      */

434     public void setFloat(float val, int row) throws DataTypeException {
435         if ( canSetFloat() ) {
436             set(new Float JavaDoc(val), row);
437         } else {
438             throw new DataTypeException(float.class);
439         }
440     }
441     
442     // -- double --------------------------------------------------------------
443

444     /**
445      * Indicates if convenience get method can be called without
446      * an exception being thrown for the double type.
447      * @return true if getDouble is supported, false otherwise
448      */

449     public boolean canGetDouble() {
450         return canGet(double.class);
451     }
452     
453     /**
454      * Indicates if convenience set method can be called without
455      * an exception being thrown for the double type.
456      * @return true if setDouble is supported, false otherwise
457      */

458     public boolean canSetDouble() {
459         return canSet(double.class);
460     }
461     
462     /**
463      * Get the data value at the specified row as a double
464      * @param row the row from which to retrieve the value
465      * @return the data value as a double
466      * @throws DataTypeException if this column does not
467      * support the double type
468      */

469     public double getDouble(int row) throws DataTypeException {
470         if ( canGetDouble() ) {
471             return ((Double JavaDoc)get(row)).doubleValue();
472         } else {
473             throw new DataTypeException(double.class);
474         }
475     }
476     
477     /**
478      * Set the data value at the specified row as a double
479      * @param val the value to set
480      * @param row the row at which to set the value
481      * @throws DataTypeException if this column does not
482      * support the double type
483      */

484     public void setDouble(double val, int row) throws DataTypeException {
485         if ( canSetDouble() ) {
486             set(new Double JavaDoc(val), row);
487         } else {
488             throw new DataTypeException(double.class);
489         }
490     }
491     
492     // -- boolean -------------------------------------------------------------
493

494     /**
495      * Indicates if convenience get method can be called without
496      * an exception being thrown for the boolean type.
497      * @return true if getBoolean is supported, false otherwise
498      */

499     public boolean canGetBoolean() {
500         return canGet(boolean.class);
501     }
502     
503     /**
504      * Indicates if convenience set method can be called without
505      * an exception being thrown for the boolean type.
506      * @return true if setBoolean is supported, false otherwise
507      */

508     public boolean canSetBoolean() {
509         return canSet(boolean.class);
510     }
511     
512     /**
513      * Get the data value at the specified row as a boolean
514      * @param row the row from which to retrieve the value
515      * @return the data value as a boolean
516      * @throws DataTypeException if this column does not
517      * support the boolean type
518      */

519     public boolean getBoolean(int row) throws DataTypeException {
520         if ( canGetBoolean() ) {
521             return ((Boolean JavaDoc)get(row)).booleanValue();
522         } else {
523             throw new DataTypeException(boolean.class);
524         }
525     }
526     
527     /**
528      * Set the data value at the specified row as a boolean
529      * @param val the value to set
530      * @param row the row at which to set the value
531      * @throws DataTypeException if this column does not
532      * support the boolean type
533      */

534     public void setBoolean(boolean val, int row) throws DataTypeException {
535         if ( canSetBoolean() ) {
536             set(new Boolean JavaDoc(val), row);
537         } else {
538             throw new DataTypeException(boolean.class);
539         }
540     }
541     
542     // -- String --------------------------------------------------------------
543

544     /**
545      * Indicates if convenience get method can be called without
546      * an exception being thrown for the String type.
547      * @return true if getString is supported, false otherwise
548      */

549     public boolean canGetString() {
550         return true;
551         //return canGet(String.class);
552
}
553     
554     /**
555      * Indicates if convenience set method can be called without
556      * an exception being thrown for the String type.
557      * @return true if setString is supported, false otherwise
558      */

559     public boolean canSetString() {
560         return m_parser != null && !(m_parser instanceof ObjectParser);
561         //return canSet(String.class);
562
}
563     
564     /**
565      * Get the data value at the specified row as a String
566      * @param row the row from which to retrieve the value
567      * @return the data value as a String
568      * @throws DataTypeException if this column does not
569      * support the String type
570      */

571     public String JavaDoc getString(int row) throws DataTypeException {
572         if ( canGetString() ) {
573             return m_parser.format(get(row));
574         } else {
575             throw new DataTypeException(String JavaDoc.class);
576         }
577     }
578     
579     /**
580      * Set the data value at the specified row as a String
581      * @param val the value to set
582      * @param row the row at which to set the value
583      * @throws DataTypeException if this column does not
584      * support the String type
585      */

586     public void setString(String JavaDoc val, int row) throws DataTypeException {
587         try {
588             set(m_parser.parse(val), row);
589         } catch (DataParseException e) {
590             throw new DataTypeException(e);
591         }
592     }
593     
594     // -- Date ----------------------------------------------------------------
595

596     /**
597      * Indicates if convenience get method can be called without
598      * an exception being thrown for the Date type.
599      * @return true if getDate is supported, false otherwise
600      */

601     public boolean canGetDate() {
602         return canGet(Date JavaDoc.class);
603     }
604     
605     /**
606      * Indicates if convenience set method can be called without
607      * an exception being thrown for the Date type.
608      * @return true if setDate is supported, false otherwise
609      */

610     public boolean canSetDate() {
611         return canSet(Date JavaDoc.class);
612     }
613     
614     /**
615      * Get the data value at the specified row as a Date
616      * @param row the row from which to retrieve the value
617      * @return the data value as a Date
618      * @throws DataTypeException if this column does not
619      * support the Date type
620      */

621     public Date JavaDoc getDate(int row) throws DataTypeException {
622         if ( canGetDate() ) {
623             return (Date JavaDoc)get(row);
624         } else {
625             throw new DataTypeException(Date JavaDoc.class);
626         }
627     }
628     
629     /**
630      * Set the data value at the specified row as a Date
631      * @param val the value to set
632      * @param row the row at which to set the value
633      * @throws DataTypeException if this column does not
634      * support the Date type
635      */

636     public void setDate(Date JavaDoc val, int row) throws DataTypeException {
637         set(val, row);
638     }
639     
640 } // end of abstract class AbstractColumn
641
Popular Tags