/* ResultSetTableModel.java
* Copyright 2000-2008 O'Reilly Media, Inc. All Rights Reserved.
*
* This file is distributed as part of the project "Crop Planning Software".
* For more information:
* website: http://cropplanning.googlecode.com
* email: cropplanning@gmail.com
*
* The source for this class was originally found at:
*
* http://www.oreillynet.com/oreilly/java/news/javaex_code.zip
*
* With an accompanying article here:
*
* http://www.oreillynet.com/pub/a/oreilly/java/news/javaex_1000.html
*
* No statement is made at that site regarding the licensing of this source
* code. As such we are using it AS IS and WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE.
*
*/
package resultsettablemodel;
import java.sql.*;
import javax.swing.table.*;
import javax.swing.event.*;
/**
* This class takes a JDBC ResultSet object and implements the TableModel
* interface in terms of it so that a Swing JTable component can display the
* contents of the ResultSet. Note that it requires a scrollable JDBC 2.0
* ResultSet. Also note that it provides read-only access to the results
**/
public class ResultSetTableModel extends AbstractTableModel {
// public class ResultSetTableModel implements TableModel {
protected ResultSet results; // The ResultSet to interpret
protected ResultSetMetaData metadata; // Additional information about the results
int numcols, numrows; // How many rows and columns in the table
/**
* This constructor creates a TableModel from a ResultSet. It is package
* private because it is only intended to be used by
* ResultSetTableModelFactory, which is what you should use to obtain a
* ResultSetTableModel
**/
protected ResultSetTableModel(ResultSet res) throws SQLException {
this.results = res; // Save the results
metadata = results.getMetaData(); // Get metadata on them
numcols = metadata.getColumnCount(); // How many columns?
results.last(); // Move to last row
numrows = results.getRow(); // How many rows?
}
/**
* Call this when done with the table model. It closes the ResultSet and
* the Statement object used to create it.
**/
public void close() {
try { results.getStatement().close(); }
catch(SQLException e) {};
}
/** Automatically close when we're garbage collected */
protected void finalize() { close(); }
// These two TableModel methods return the size of the table
public int getColumnCount() { return numcols; }
public int getRowCount() { return numrows; }
// This TableModel method returns columns names from the ResultSetMetaData
public String getColumnName(int column) {
try {
return metadata.getColumnLabel(column+1);
} catch (SQLException e) { return e.toString(); }
}
// This TableModel method specifies the data type for each column.
// We could map SQL types to Java types, but for this example, we'll just
// convert all the returned data to strings.
public Class getColumnClass(int column) { return String.class; }
/**
* This is the key method of TableModel: it returns the value at each cell
* of the table. We use strings in this case. If anything goes wrong, we
* return the exception as a string, so it will be displayed in the table.
* Note that SQL row and column numbers start at 1, but TableModel column
* numbers start at 0.
**/
public Object getValueAt(int row, int column) {
try {
results.absolute(row+1); // Go to the specified row
Object o = results.getObject(column+1); // Get value of the column
if (o == null) return null;
else return o.toString(); // Convert it to a string
} catch (SQLException e) { return e.toString(); }
}
// Our table isn't editable
public boolean isCellEditable(int row, int column) { return false; }
// Since its not editable, we don't need to implement these methods
// commented out 4/3/07 so that we can override this class to be editable
// public void setValueAt(Object value, int row, int column) {}
// public void addTableModelListener(TableModelListener l) {}
// public void removeTableModelListener(TableModelListener l) {}
}