package prefuse.data.column; import java.util.Date; import prefuse.data.DataTypeException; import prefuse.data.event.ColumnListener; import prefuse.data.parser.DataParseException; import prefuse.data.parser.DataParser; import prefuse.data.parser.ObjectParser; import prefuse.data.parser.ParserFactory; import prefuse.util.TypeLib; import prefuse.util.collections.CopyOnWriteArrayList; /** * Abstract base class for Column implementations. Provides listener support * and default implementations of column methods. * * @author jeffrey heer */ public abstract class AbstractColumn implements Column { protected final Class m_columnType; protected DataParser m_parser; protected Object m_defaultValue; protected boolean m_readOnly; protected CopyOnWriteArrayList m_listeners; /** * Create a new AbstractColumn of type Object. */ public AbstractColumn() { this(Object.class, null); } /** * Create a new AbstractColumn of a given type. * @param columnType the data type stored by this column */ public AbstractColumn(Class columnType) { this(columnType, null); } /** * Create a new AbstractColumn of a given type. * @param columnType the data type stored by this column * @param defaultValue the default data value to use */ public AbstractColumn(Class columnType, Object defaultValue) { m_columnType = columnType; DataParser p = ParserFactory.getDefaultFactory().getParser(columnType); m_parser = ( p==null ? new ObjectParser() : p ); setDefaultValue(defaultValue); m_readOnly = false; m_listeners = new CopyOnWriteArrayList(); } // ------------------------------------------------------------------------ // Column Metadata /** * Indicates if the values in this column are read-only. * @return true if the values can not be edited, false otherwise */ public boolean isReadOnly() { return m_readOnly; } /** * Sets if the values in this column are read-only * @param readOnly true to ensure the values can not be edited, * false otherwise */ public void setReadOnly(boolean readOnly) { m_readOnly = readOnly; } // /** * Indicates if the value at the given row can be edited. * @param row the row to check * @return true is the value can be modified, false otherwise */ public boolean isCellEditable(int row) { return !m_readOnly; } /** * Returns the most specific superclass for the values in the column * @return the Class of the column's data values */ public Class getColumnType() { return m_columnType; } /** * @see prefuse.data.column.Column#getParser() */ public DataParser getParser() { return m_parser; } /** * @see prefuse.data.column.Column#setParser(prefuse.data.parser.DataParser) */ public void setParser(DataParser parser) { if ( !m_columnType.isAssignableFrom(parser.getType()) ) { throw new IllegalArgumentException( "Parser type ("+parser.getType().getName()+") incompatible with" +" this column's data type ("+m_columnType.getName()+")"); } m_parser = parser; } // ------------------------------------------------------------------------ // Listener Methods /** * Adds a listener to be notified when this column changes * @param listener the ColumnListener to add */ public void addColumnListener(ColumnListener listener) { m_listeners.add(listener); } /** * Removes a listener, causing it to no longer be notified of changes * @param listener the ColumnListener to remove */ public void removeColumnListener(ColumnListener listener) { m_listeners.remove(listener); } /** * Notifies all registered listeners of a column UPDATE event */ protected final void fireColumnEvent(int type, int start, int end) { Object[] lstnrs = m_listeners.getArray(); for ( int i=0; i