CS 411 Example of TableModel which updates JTable Entries jdbcodbc driver loaded oracle driver loaded Connected to jdbc:oracle:thin:@cpe.bridgeport.edu:1521:csdb Driver Oracle JDBC driver Version 8.1.6.0.0 Got 5 columns Got 2 rows In setValueAt() x=1 y = 2 updated 1 row In setValueAt() x=1 y = 4 updated 1 row //---------------------------------------------------------------------------// // Module: DBJTableBean3.java // // Author: Julius Dichter 2003 (c) (revised) // // Description: Java Bean for ODBC API interface. It uses the JDBC calls into // a database. Then we create a swing class table and load it up // with the data from the ResultSet and ResultSetMetaData. All the // is for display only. It can be modified, but there is no // database updating implemented // // CS 411 assignment to makes update calls through updateRow() Updatable ResultSet. // // A JComboBox is used as a default editor for the state column. // The JScrollPane has a lowered beveled border // // We now update the database whenever a user changes a row // Key fields Last and First are NOT updatable // // // !!!!!!!!!!!!!!!!!!!!!!!!!!!! // It is integreated with MyTableModel // !!!!!!!!!!!!!!!!!!!!!!!!!!!! //---------------------------------------------------------------------------import java.net.URL; import java.sql.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.Dimension; import javax.swing.*; import javax.swing.table.*; import javax.swing.border.*; public class DBJTableBean3 extends JPanel { ResultSet rs; Connection con; Statement stmt; String url; public static void main (String args[]) { JFrame frame = new JFrame("Database Query"); String user = args[0]; String password = args[1]; frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.out.println("Closing Program"); System.exit(0); } } ); frame.setBounds(200,200,500,400); DBJTableBean3 bean = new DBJTableBean3(user, password); frame.getContentPane().add(bean); frame.show(); } public void finalize() { try { rs.close(); stmt.close(); con.close(); } catch (SQLException sqle) { } } public DBJTableBean3 (String user, String password) { url = "jdbc:oracle:thin:@cpe.bridgeport.edu:1521:csdb"; //url = "jdbc:odbc:names"; // Modify SQL Select with Table Alias String query = "SELECT T.* FROM People T"; try { Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); System.out.println("jdbcodbc driver loaded"); Class.forName ("oracle.jdbc.driver.OracleDriver"); // find the class System.out.println("oracle driver loaded"); con = DriverManager.getConnection (url, user, password); checkForWarning (con.getWarnings ()); DatabaseMetaData dma = con.getMetaData (); System.out.println("\nConnected to " + dma.getURL()); System.out.println("Driver " + dma.getDriverName()); System.out.println("Version " + dma.getDriverVersion()); System.out.println(""); stmt = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); ResultSet rs; rs = stmt.executeQuery (query); rs.setFetchDirection(ResultSet.FETCH_UNKNOWN); // Now interogate the rs in order to build the 2-D array to hold rs data // note: the folowing three need to be final final int cols = rs.getMetaData().getColumnCount(); final int rows = getRowCount(rs); // calling a local method System.out.println("Got " + cols + " columns"); System.out.println("Got " + rows + " rows"); final Object [][] data = new Object[rows][cols]; final String [] colNames = new String[cols]; // reexecute query to get to beginning of data rs = stmt.executeQuery (query); // load the data Object array for (int i = 0; i < rows ; i++) { rs.next(); for (int j = 0 ; j < cols ; j++) data[i][j] = rs.getString(j+1); } for (int i = 0 ; i < cols ; i++) colNames[i] = rs.getMetaData().getColumnName(i+1); MyTableModel tableModel = new MyTableModel(data, colNames); tableModel.setResultSet(rs); JTable tableView = new JTable(tableModel); JScrollPane sPane = new JScrollPane(tableView); sPane.setBorder(new BevelBorder(BevelBorder.LOWERED)); sPane.setPreferredSize(new Dimension(430,260)); add(sPane); setVisible(true); } catch (SQLException ex) { System.out.println ("\n*** SQLException caught ***\n"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState ()); System.out.println ("Message: " + ex.getMessage ()); System.out.println ("Vendor: " + ex.getErrorCode ()); ex = ex.getNextException (); System.out.println (""); } } catch (java.lang.Exception ex) { // Got some other type of exception. Dump it. ex.printStackTrace (); } } public String getUrl() { return url; } public void setUrl(String s) { url = new String(s); } private static boolean checkForWarning (SQLWarning warn) throws SQLException { boolean rc = false; if (warn != null) { System.out.println ("\n *** Warning ***\n"); rc = true; while (warn != null) { System.out.println ("SQLState: " + warn.getSQLState ()); System.out.println ("Message: " + warn.getMessage ()); System.out.println ("Vendor: " + warn.getErrorCode ()); System.out.println (""); warn = warn.getNextWarning (); } } return rc; } private static void dispResultSet (ResultSet rs) throws SQLException { int i; ResultSetMetaData rsmd = rs.getMetaData (); // Get the number of columns in the result set int numCols = rsmd.getColumnCount (); // Display column headings for (i=1; i<=numCols; i++) { if (i > 1) System.out.print(","); System.out.print(rsmd.getColumnLabel(i)); } System.out.println(""); // Display data, fetching until end of the result set while (rs.next ()) { // Loop through each column, getting the // column data and displaying for (i=1; i<=numCols; i++) { if (i > 1) System.out.print(","); System.out.print(rs.getString(i)); } System.out.println(""); // Fetch the next result set row } } private int getRowCount(ResultSet rs) throws SQLException { int count = 0; while ( rs.next() ) count ++ ; return count; } private static void dispJTableResultSet (ResultSet rs) throws SQLException { int i; // Get the ResultSetMetaData. This will be used for // the column headings ResultSetMetaData rsmd = rs.getMetaData (); // Get the number of columns in the result set int numCols = rsmd.getColumnCount (); // Display column headings for (i=1; i<=numCols; i++) { if (i > 1) System.out.print(","); System.out.print(rsmd.getColumnLabel(i)); } System.out.println(""); // Display data, fetching until end of the result set while (rs.next ()) { // Loop through each column, getting the // column data and displaying for (i=1; i<=numCols; i++) { if (i > 1) System.out.print(","); System.out.print(rs.getString(i)); } System.out.println(""); // Fetch the next result set row } } } // class DBJTableBean //---------------------------------------------------------------------------// // Module: MyTableModel.java // // Author: Julius Dichter 2003 (c) // // Description: // // // This is a class which extends the AbstractTableModel implements TableModel we get a 2-D array of Object as the dataset, and an array of column names we can set thew ResultSet allowing updates to be made to the database // Note: The following assumptions must hold regarding the Statement and ResultSet // Statement // stmt = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); // // ResultSet rs.setFetchDirection(ResultSet.FETCH_UNKNOWN); import java.sql.*; import javax.swing.table.*; public class MyTableModel extends AbstractTableModel implements TableModel { private ResultSet rs; private Object [][] data; private Object []column; public MyTableModel (Object [] [] data, Object [] column) { this.data = data; this.column = column; } public void setResultSet (ResultSet rs) { this.rs = rs; } public int getColumnCount() { return column.length; } public int getRowCount() { return data.length; } public Object getValueAt(int x, int y) { return data[x][y]; } public boolean isCellEditable(int row, int col) { return col != 0 && col != 1; } public String getColumnName(int i) { return String.valueOf(column[i]); } // We update the database here // the +1 factor is a correction between the ResultSet indexinf and the 2-D array indexing public void setValueAt(Object o, int x, int y) { String cellValue = o.toString(); data[x][y] = o; // store the original value; // set the new value try { System.out.println("In setValueAt() x=" + x + " y = " + y); boolean ok = rs.absolute(x+1); // move to row x rs.updateString( y+1, String.valueOf(data[x][y] )); // modify to y, data[x][y] rs.updateRow(); System.out.println("updated 1 row"); } catch (SQLException sqle) { sqle.printStackTrace(); } } } // MyTableModel