org.jdesktop.jdnc.table
Class DefaultTableModelExt

java.lang.Object
  extended by javax.swing.table.AbstractTableModel
      extended by org.jdesktop.jdnc.table.DefaultTableModelExt
All Implemented Interfaces:
java.io.Serializable, javax.swing.table.TableModel, MetaDataProvider

public class DefaultTableModelExt
extends javax.swing.table.AbstractTableModel
implements MetaDataProvider

Class used to represent a tabular data model which holds 2 dimensional data. This class provides a simple alternative to javax.sql.RowSet and is intended for use when the program is not obtaining its data directly from a JDBC data source. Programs which are interfacing with databases using JDBC should use the RowSet API instead.

A tabular data model is structured with a fixed number of columns where each column is represented by an integer index. The first column's index is 0 and the last column's index is columnCount - 1. Each column in the tabular data model has a MetaData instance which describes the column's data-type and edit constraints.

The structure of the model (number of columns and associated column meta-data which describes those columns) must be initialized before the rows of data are loaded into the model. The structure can be obtained directly from the data source (if set) or it can be set explicitly by the program. The following example configures the table's structure explicitly:


     DefaultTableModelExt data = new DefaultTableModelExt();
     data.setColumnCount(3);

     MetaData columnMetaData = data.getColumnMetaData(0);
     columnMetaData.setName("firstname");
     columnMetaData = data.getColumnMetaData(1);
     columnMetaData.setName("lastname");
     columnMetaData = data.getColumnMetaData(2);
     columnMetaData.setName("employeeid");
     columnMetaData.setElementClass(Integer.class);
 

If the meta-data properties for each column are not explicitly set, the type of each column will default to java.lang.String.

The data for the model may be loaded either by explicitly invoking the addRows or insertRows method, or by setting the "source" property, in which case the tabular data model will handle streaming the data in from that source when startLoading is called. The format of the data at that source URL must be readible by the DataLoader instance set as the "loader" property. By default the loader is set to a TableModelExtTextLoader instance, which can read the data in simple ascii format where the columns are separated by configurable regular expression delimeters. Examples of this format are tab-separated-values (TSV) and comma-separated-values (CSV). If the data at the source is coming in an alternate format, the caller is responsible for setting an appropriate loader object before invoking startLoading.

If the data for the above example was available from a tsv file, the tabular data model could be loaded with the following code:


     data.setSource("file:///D:/acme/employees.tsv");
     data.startLoading();
 

It is often desirable to determine the structure of the tabular data model (number of columns, types, etc) from the source rather than setting it explicitly. The amount of structural information available from a source will depend on the format of the data. The plain text formats do not typically contain meta-data information beyond optional column names encoded as the first row, and thus it is desirable to explicitly configure the column meta-data for these simple formats.

Once the data has been loaded into the model, values at a specific row and column may be retreived or modified. For example:


     int rowCount = data.getRowCount();
     for (int i = 0; i < rowCount; i++) {
         Float payrate = (Float)data.getValueAt(i, 4);
         if (payrate < 10.00) {
             // underpaid - give raise
             data.setValueAt(i, 4, new Float(payrate*.05));
         }
     }
 

Additionally, rows can be inserted or deleted. Example:

     // hired
     Object employee[] = new Object[4];
     employee[0] = "Einstein";
     employee[1] = "Albert";
     employee[2] = new Integer(430);
     employee[3] = new Float(12.50);
     data.insertRow(5, employee);

     // fired
     data.deleteRow(6);
 

This class is also an instance of javax.swing.table.TableModel and thus can be set as the model for any javax.swing.JTable component instance.

DefaultTableModelExt generates table model events when either its structure or values are modified. To listen for these events, register a TableModelListener instance. Example:


     DefaultTableModelExt data = new DefaultTableModelExt("http://www.foo.com/barQuery");
     data.addTableModelListener(new TableModelListener() {
         public void tableChanged(TableModelEvent e) {
              // handle tabular data model change
         }
     });
 

Version:
1.0
Author:
Amy Fowler
See Also:
MetaData, TableModel, TableModelEvent, TableModelListener, TableModelExtTextLoader, Serialized Form

Field Summary
 
Fields inherited from class javax.swing.table.AbstractTableModel
listenerList
 
Constructor Summary
DefaultTableModelExt()
          Creates a new tabular data model with 0 columns.
DefaultTableModelExt(int columnCount)
          Creates a new tabular data model with the specified number of columns.
DefaultTableModelExt(java.lang.String urlName)
          Creates a new tabular data model configured to obtain its data in plain text format from the specified URL.
DefaultTableModelExt(java.lang.String urlName, int columnCount)
          Creates a new tabular data model configured to obtain its data in plain text format from the specified URL.
DefaultTableModelExt(java.net.URL sourceURL)
          Create a new tabular data model configured to obtain its data in plain text format from the specified URL.
 
Method Summary
 void addPropertyChangeListener(java.beans.PropertyChangeListener pcl)
          Adds the specified property change listener to this tabular data model.
 void addRow(java.lang.Object[] row)
          Adds a new row at the end of the tabular data model.
 void addRows(java.util.List rows)
          Adds a collection of new rows at the end of the tabular data model.
 void deleteRow(int rowIndex)
          Deletes the row at the specified row index from the tabular data model.
 void deleteRows(int firstRowIndex, int lastRowIndex)
          Deletes the contiguous set of rows in the specified range from this tabular data model.
 java.lang.Class getColumnClass(int columnIndex)
          Returns the value of the specified column's meta-data "elementClass" property.
 int getColumnCount()
          Returns the number of columns in this tabular data model.
 int getColumnIndex(java.lang.String columnName)
          Note that the columnName parameter must be the "name" of the column as stored in the column's MetaData and should not be confused with the getColumnName method from TableModel, which actually refers to the "label" property on the MetaData.
 MetaData getColumnMetaData(int columnIndex)
          Returns the meta-data for the specified column.
 java.lang.String getColumnName(int columnIndex)
          Returns the value of the specified column's meta-data "label" property.
 int getFieldCount()
           
 java.lang.String[] getFieldNames()
          Note: if the type for id is changed to Object type this will have to change to returning Object[].
 DataLoader getLoader()
          Returns a TableModelExtTextLoader instance by default, which can read data in plain text format where rows are separated by newlines and columns within each row are separated by the tab character (delimeters are configurable).
 MetaData[] getMetaData()
          If the data source is non-null and the number of columns has not yet been initialized, this method will attempt to initialize the number of columns by reading any available meta-data from the source.
 MetaData getMetaData(java.lang.String columnName)
          Note: String will likely be converted to type Object for the ID
 java.beans.PropertyChangeListener[] getPropertyChangeListeners()
           
 java.lang.Object[] getRow(int rowIndex)
          Returns the contents of the row at the specified row index.
 int getRowCount()
           
 java.net.URL getSource()
           
 java.lang.Object getValueAt(int rowIndex, int columnIndex)
           
 void insertRow(int rowIndex, java.lang.Object[] row)
          Inserts a new row in the tabular data model at the specified row index.
 void insertRows(int rowIndex, java.util.List rows)
          Inserts a collection of new rows into the tabular data model at the specified row index.
 boolean isCellEditable(int rowIndex, int columnIndex)
          Returns the negation of the specified column's meta-data "readOnly" property.
 boolean isLoading()
           
 void removePropertyChangeListener(java.beans.PropertyChangeListener pcl)
          Removes the specified property change listener from this tabular data model.
 void setColumnCount(int columnCount)
          Initializes the number of columns in this tabular data model and creates new instances of column MetaData objects for each column.
 void setColumnMetaData(int columnIndex, MetaData metaData)
          Sets the meta data object for the specified column.
 void setLoader(DataLoader loader)
          Sets the data loader object to be used to stream in the data from the source URL.
 void setSource(java.lang.String urlName)
          Sets the "source" URL property after converting the URL string to a URL instance.
 void setSource(java.net.URL sourceURL)
          Sets the "source" property.
 void setValueAt(java.lang.Object value, int rowIndex, int columnIndex)
          Sets the value of the tabular data element at the specified row and column.
 void startLoading()
          Starts loading the data asynchronously from the tabular data object's source.
 
Methods inherited from class javax.swing.table.AbstractTableModel
addTableModelListener, findColumn, fireTableCellUpdated, fireTableChanged, fireTableDataChanged, fireTableRowsDeleted, fireTableRowsInserted, fireTableRowsUpdated, fireTableStructureChanged, getListeners, getTableModelListeners, removeTableModelListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DefaultTableModelExt

public DefaultTableModelExt()
Creates a new tabular data model with 0 columns.


DefaultTableModelExt

public DefaultTableModelExt(int columnCount)
Creates a new tabular data model with the specified number of columns.

Parameters:
columnCount - integer indicating the number of columns in this tabular data model
Throws:
java.lang.IllegalArgumentException - if columnCount < 0

DefaultTableModelExt

public DefaultTableModelExt(java.lang.String urlName)
                     throws java.net.MalformedURLException
Creates a new tabular data model configured to obtain its data in plain text format from the specified URL.

Parameters:
urlName - String containing the name of the URL which provides the data for this tabular data model
Throws:
java.net.MalformedURLException - if urlName cannot be converted to a valid URL

DefaultTableModelExt

public DefaultTableModelExt(java.net.URL sourceURL)
Create a new tabular data model configured to obtain its data in plain text format from the specified URL.

Parameters:
sourceURL - URL which provides the data for this tabular data model

DefaultTableModelExt

public DefaultTableModelExt(java.lang.String urlName,
                            int columnCount)
                     throws java.net.MalformedURLException
Creates a new tabular data model configured to obtain its data in plain text format from the specified URL. The number of columns will be initialized to the specified column count.

Parameters:
urlName - String containing the name of the URL which provides the data for this tabular data model
columnCount - integer indicating the number of columns in this tabular data model
Throws:
java.lang.IllegalArgumentException - if columnCount < 0
java.net.MalformedURLException - if urlName cannot be converted to a valid URL
Method Detail

setSource

public void setSource(java.lang.String urlName)
               throws java.net.MalformedURLException
Sets the "source" URL property after converting the URL string to a URL instance.

Parameters:
urlName - String containing the name of the URL which provides the data for this tabular data model
Throws:
java.net.MalformedURLException - if urlName cannot be converted to a valid URL
See Also:
getSource()

setSource

public void setSource(java.net.URL sourceURL)
Sets the "source" property.

Parameters:
sourceURL - URL which provides the data for this tabular data model
See Also:
getSource()

getSource

public java.net.URL getSource()
Returns:
URL which provides the data for this tabular data model
See Also:
setSource(java.lang.String)

setLoader

public void setLoader(DataLoader loader)
Sets the data loader object to be used to stream in the data from the source URL.

Parameters:
loader - DataLoader object which can read data in the format provided from the source
See Also:
getLoader()

getLoader

public DataLoader getLoader()
Returns a TableModelExtTextLoader instance by default, which can read data in plain text format where rows are separated by newlines and columns within each row are separated by the tab character (delimeters are configurable).

Returns:
DataLoader object which can read data in the format provided from the source
See Also:
TableModelExtTextLoader, setLoader(org.jdesktop.jdnc.DataLoader)

getColumnCount

public int getColumnCount()
Returns the number of columns in this tabular data model. If the data source is non-null and the number of columns has not yet been initialized, this method will attempt to initialize the number of columns by reading any available meta-data from the source.

Specified by:
getColumnCount in interface javax.swing.table.TableModel
Returns:
integer indicating the number of columns in this tabular data model

setColumnCount

public void setColumnCount(int columnCount)
Initializes the number of columns in this tabular data model and creates new instances of column MetaData objects for each column. Each column meta-data object will default to type String and will have a column name "column+<columnIndex>". This method will also cause any existing rows of data to be cleared so that rowCount will be 0.

Parameters:
columnCount - integer indicating the number of columns in this tabular data model
Throws:
java.lang.IllegalArgumentException - if columnCount < 0

getColumnMetaData

public MetaData getColumnMetaData(int columnIndex)
Returns the meta-data for the specified column. If the data source is non-null and the number of columns has not yet been initialized, this method will attempt to initialize the number of columns by reading any available meta-data from the source.

Parameters:
columnIndex - integer index indicating column in tabular data model
Returns:
MetaData object describing the data element at the specified column
Throws:
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount

getMetaData

public MetaData getMetaData(java.lang.String columnName)
Description copied from interface: MetaDataProvider
Note: String will likely be converted to type Object for the ID

Specified by:
getMetaData in interface MetaDataProvider
Parameters:
columnName - String containing the id for the column
Returns:
MetaData object describing the data element at the specified column

getMetaData

public MetaData[] getMetaData()
If the data source is non-null and the number of columns has not yet been initialized, this method will attempt to initialize the number of columns by reading any available meta-data from the source.

Specified by:
getMetaData in interface MetaDataProvider
Returns:
array containing the MetaData objects for each column in the tabular data model

getFieldNames

public java.lang.String[] getFieldNames()
Description copied from interface: MetaDataProvider
Note: if the type for id is changed to Object type this will have to change to returning Object[].

Specified by:
getFieldNames in interface MetaDataProvider
Returns:
array containing the names of all data fields in this map

getFieldCount

public int getFieldCount()
Specified by:
getFieldCount in interface MetaDataProvider
Returns:
integer containing the number of contained MetaData

setColumnMetaData

public void setColumnMetaData(int columnIndex,
                              MetaData metaData)
Sets the meta data object for the specified column.

Parameters:
columnIndex - integer index indicating column in tabular data model
metaData - object describing the data element at the specified column
Throws:
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount

getColumnClass

public java.lang.Class getColumnClass(int columnIndex)
Returns the value of the specified column's meta-data "elementClass" property.

Specified by:
getColumnClass in interface javax.swing.table.TableModel
Overrides:
getColumnClass in class javax.swing.table.AbstractTableModel
Parameters:
columnIndex - integer index indicating column in tabular data model
Returns:
Class indicating column data element's type
Throws:
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount
See Also:
MetaData.getElementClass()

getColumnName

public java.lang.String getColumnName(int columnIndex)
Returns the value of the specified column's meta-data "label" property. Note: javax.swing.table.TableModel specifies this method returns the header value, which is why this returns the label and not the name.

Specified by:
getColumnName in interface javax.swing.table.TableModel
Overrides:
getColumnName in class javax.swing.table.AbstractTableModel
Parameters:
columnIndex - integer index indicating column in tabular data model
Returns:
String containing the column's label
Throws:
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount
See Also:
MetaData.getLabel()

isCellEditable

public boolean isCellEditable(int rowIndex,
                              int columnIndex)
Returns the negation of the specified column's meta-data "readOnly" property.

Specified by:
isCellEditable in interface javax.swing.table.TableModel
Overrides:
isCellEditable in class javax.swing.table.AbstractTableModel
Parameters:
rowIndex - integer index indicating row in tabular data model
columnIndex - integer index indicating column in tabular data model
Returns:
boolean indicating whether or not the tabular data element value at the specified row and column may be modified
Throws:
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount or rowIndex < 0 or rowIndex >= rowCount
See Also:
MetaData.isReadOnly()

getRowCount

public int getRowCount()
Specified by:
getRowCount in interface javax.swing.table.TableModel
Returns:
integer indicating the number of rows currently in this tabular data model

getValueAt

public java.lang.Object getValueAt(int rowIndex,
                                   int columnIndex)
Specified by:
getValueAt in interface javax.swing.table.TableModel
Parameters:
rowIndex - integer index indicating row in tabular data model
columnIndex - integer index indicating column in tabular data model
Returns:
Object containing value of tabular data element at the specified row and column
Throws:
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount or rowIndex < 0 or rowIndex >= rowCount

setValueAt

public void setValueAt(java.lang.Object value,
                       int rowIndex,
                       int columnIndex)
Sets the value of the tabular data element at the specified row and column. The caller is responsible for ensuring the object is an instance of the column's class.

Specified by:
setValueAt in interface javax.swing.table.TableModel
Overrides:
setValueAt in class javax.swing.table.AbstractTableModel
Parameters:
value - Object containing value of tabular data element
rowIndex - integer index indicating row in tabular data model
columnIndex - integer index indicating column in tabular data model
Throws:
java.lang.RuntimeException - if the column is not editable
java.lang.IndexOutOfBoundsException - if columnIndex < 0 or columnIndex >= columnCount or rowIndex < 0 or rowIndex >= rowCount
See Also:
getColumnClass(int), isCellEditable(int, int)

deleteRow

public void deleteRow(int rowIndex)
Deletes the row at the specified row index from the tabular data model.

Parameters:
rowIndex - integer index indicating row in tabular data model
Throws:
java.lang.IndexOutOfBoundsException - if rowIndex < 0 or rowIndex >= rowCount

deleteRows

public void deleteRows(int firstRowIndex,
                       int lastRowIndex)
Deletes the contiguous set of rows in the specified range from this tabular data model.

Parameters:
firstRowIndex - integer index indicating first row in range
lastRowIndex - integer index indicating last row in range
Throws:
java.lang.IllegalArgumentException - if lastRowIndex < firstRowIndex
java.lang.IndexOutOfBoundsException - if firstRowIndex < 0 or firstRowIndex >= rowCount or lastRowIndex < 0 or lastRowIndex >= rowCount

insertRow

public void insertRow(int rowIndex,
                      java.lang.Object[] row)
Inserts a new row in the tabular data model at the specified row index. The elements in the row array are copied into the tabular data model, therefore subsequent changes to the content of the row parameter will have no affect on the contents of the tabular data model.

Parameters:
rowIndex - integer index indicating row in tabular data model
row - array containing the column elements for the row
Throws:
java.lang.IndexOutOfBoundsException - if rowIndex < 0 or rowIndex >= rowCount

insertRows

public void insertRows(int rowIndex,
                       java.util.List rows)
Inserts a collection of new rows into the tabular data model at the specified row index. Each element in the collection must be an array of objects with a length equal to the number of columns in this tabular data model. The elements in the row arrays are copied into the tabular data model, therefore subsequent changes to the content of the rows parameter will have no affect on the contents of the tabular data model.

Parameters:
rowIndex - integer index indicating row in tabular data model
rows - list containing an object array for each row to be added
Throws:
java.lang.IndexOutOfBoundsException - if rowIndex < 0 or rowIndex >= rowCount

addRow

public void addRow(java.lang.Object[] row)
Adds a new row at the end of the tabular data model. The elements in the row array are copied into the tabular data model, therefore subsequent changes to the content of the row array parameter will have no affect on the contents of the tabular data model.

Parameters:
row - array containing the column elements for the row

addRows

public void addRows(java.util.List rows)
Adds a collection of new rows at the end of the tabular data model. Each element in the collection must be an array of objects with a length equal to the number of columns in this tabular data model. The elements in the rows list are copied into the tabular data model, therefore subsequent changes to the content of the row parameter will have no affect on the contents of the tabular data model.

Parameters:
rows - list containing an object array for each row to be added

startLoading

public void startLoading()
                  throws java.io.IOException
Starts loading the data asynchronously from the tabular data object's source. If this tabular data object has existing data when this method is called, it will be cleared before loading any new data. This method will initiate a new thread to handle the loading and return immediately, thus it is safe to call from the UI thread.

Throws:
java.lang.IllegalStateException - if the "source" property is null
java.io.IOException

isLoading

public boolean isLoading()
Returns:
boolean indicating whether or not data is currently being loaded
See Also:
startLoading()

getRow

public java.lang.Object[] getRow(int rowIndex)
Returns the contents of the row at the specified row index. The elements in the row are copied from the tabular data model, therefore subsequent changes to the content of the returned row array will have no affect on the contents of the tabular data model. Use setValueAt to change the contents of the tabular data model.

Parameters:
rowIndex - integer index indicating row in tabular data model
Returns:
array containing the column element values for the row
Throws:
java.lang.IndexOutOfBoundsException - if rowIndex < 0 or rowIndex >= rowCount
See Also:
setValueAt(java.lang.Object, int, int)

getColumnIndex

public int getColumnIndex(java.lang.String columnName)
Note that the columnName parameter must be the "name" of the column as stored in the column's MetaData and should not be confused with the getColumnName method from TableModel, which actually refers to the "label" property on the MetaData.

Parameters:
columnName - String containing the name of the column
Returns:
integer index of column in tabular data model which corresponds to the specified column name
Throws:
java.lang.IllegalArgumentException - if the column name does not exist in this tabular data model
See Also:
MetaData.getName()

addPropertyChangeListener

public void addPropertyChangeListener(java.beans.PropertyChangeListener pcl)
Adds the specified property change listener to this tabular data model.

Parameters:
pcl - PropertyChangeListener object to receive events when tabular data model properties change

removePropertyChangeListener

public void removePropertyChangeListener(java.beans.PropertyChangeListener pcl)
Removes the specified property change listener from this tabular data model.

Parameters:
pcl - PropertyChangeListener object to receive events when tabular data model properties change

getPropertyChangeListeners

public java.beans.PropertyChangeListener[] getPropertyChangeListeners()
Returns:
array containing the PropertyChangeListener objects registered on this tabular data model


Copyright © 2005 Sun Microsystems All Rights Reserved.