Änderungen in JTable direkt an DB weitergeben

Shout

Mitglied
Hi zusammen...

Ich versuche schon seit Tagen eine JTable hinzukriegen, welche bei Änderung des Tabelleninhalts sofort die DB (aus welcher die Daten gelesen wurden) mit den geänderten Werten aktualisiert. Kann mir jemand sagen wie ich dies bewerkstelligen kann?

Danke und Gruss
 
da gibts doch sicher neinen listener in der jtable der registriert wenn sich die Daten geändert haben und dann hängst an deinen listener einfach deine Db update Methode drann , das einzige was du also machen musst ist den Listener zu schreiben deine DB update Methode existier ja sicher schon.
 
Moin,
wenn die Daten in der Tabelle editiert werden, wird die Methode setValueAt(...) aufgerufen. Dort wäre also eine entsprechende Aktualisierungsfunktion einzubauen.
Wenn die Daten in der Tabelle per Datenmodelländerung verändert werden, hat man es ja selbst in der Hand. Und eine Aktualisierung der Tabellenanzeige erreicht man fast immer durch fireTableDataChanged()
 
Toll, danke vielmal für die schnelle Antwort, das hat mir schon sehr weitergeholfen. Ich habe nun ein eigenes TableModel erstellt, welche von der Klasse AbstractTableModel abgeleitet ist. Leider habe ich dort noch ein kleines Problem:

Wie würdet Ihr die Daten am besten im TableModel speichern? Ich hab mir überlegt ein zweidimensionales Array zu erstellen. Eine Dimension für die Spalten, und eine für die Zeilen. Ist das sinnvoll?

Oder habt ihr bessere Vorschläge? Ich hab nämlich sowieso noch nicht rausbekommen wie ich die Daten vom Recordset richtig in das Array abfüllen kann.
 
Ich habs hingekriegt! Allerdings habe ich die Daten in Vektoren gespeichert, was für meine Zwecke vollkommen genügt. Vielen Dank
 
Hallo!

Hier mal ein "Brute-Force" Beispiel wie man seine JTable Eingaben direkt in die Datenbank schieben kann.

Code:
/*
 * Created on 10.12.2004@23:29:27
 *
 * TODO Explain me ...
 */
package de.tutorials;

import java.awt.Container;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

/**
 * @author Darimont
 *  
 */
public class JTableExample extends JFrame {

	private Connection con;

	private JTable table;

	private DBAwareTableModel model;

	public JTableExample() {
		super("JTableExample");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		Container c = getContentPane();
		table = new JTable();
		c.add(new JScrollPane(table));
		pack();

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				try {
					if (JTableExample.this.con != null
							&& !JTableExample.this.con.isClosed()) {
						System.out
								.println("Trying to close the remaining Connection...");
						JTableExample.this.con.close();
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		});

		setVisible(true);

	}

	public static void main(String[] args) {
		new JTableExample().start();
	}

	/**
	 *  
	 */
	private void start() {
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			MysqlDataSource ds = new MysqlDataSource();
			ds.setDatabaseName("test");
			ds.setUser("root");
			ds.setPassword("");
			ds.setServerName("localhost");
			ds.setPort(3306);

			con = (Connection) ds.getConnection();
			populateTable("SELECT id, username,password, admin FROM user");
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	/**
	 * @param string
	 */
	private void populateTable(String sql) throws SQLException {
		// TODO Auto-generated method stub
		if (con == null)
			throw new NullPointerException("con was null...");
		Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
				ResultSet.CONCUR_UPDATABLE);

		model = new DBAwareTableModel(stmt.executeQuery(sql));
		table.setEnabled(false);
		table.setModel(model);
		table.updateUI();
		table.setEnabled(true);
	}

	class DBAwareTableModel extends AbstractTableModel {

		private final String pkColumnName = "ID";

		private Object[][] data;

		private Object[] columnHeaders;

		private Class[] columnClasses;

		private ResultSet rs;

		public DBAwareTableModel(ResultSet rs) {
			if (rs == null)
				throw new NullPointerException("rs was null!");
			this.rs = rs;
			try {

				ResultSetMetaData rsmd = rs.getMetaData();
				int clmnCnt = rsmd.getColumnCount();
				columnHeaders = new Object[clmnCnt];
				columnClasses = new Class[columnHeaders.length];
				try {
					for (int i = 1; i <= clmnCnt; i++) {
						columnHeaders[i - 1] = rsmd.getColumnName(i);
						columnClasses[i - 1] = Class.forName(rsmd
								.getColumnClassName(i));
					}
				} catch (ClassNotFoundException e1) {
					e1.printStackTrace();
				}

				List rows = new ArrayList();
				while (rs.next()) {
					Object[] row = new Object[clmnCnt];
					for (int i = 1; i <= clmnCnt; i++) {
						row[i - 1] = rs.getObject(i);
					}
					rows.add(row);
				}

				data = new Object[rows.size()][];
				for (int i = 0; i < data.length; i++) {
					data[i] = (Object[]) rows.get(i);
				}

				//rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#isCellEditable(int, int)
		 */
		public boolean isCellEditable(int rowIndex, int columnIndex) {
			// TODO Auto-generated method stub

			if (table.getColumnName(columnIndex).equals(pkColumnName))
				return false;
			return true;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.AbstractTableModel#fireTableCellUpdated(int,
		 *      int)
		 */
		public void fireTableCellUpdated(int row, int column) {
			if (con == null)
				throw new NullPointerException("con was null...");
			try {

				rs.first();
				rs.absolute(row + 1);

				rs.updateObject(column + 1, table.getValueAt(row, column));
				rs.updateRow();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}

		public String getColumnName(int i) {
			if (columnHeaders == null || columnHeaders[i] == null)
				throw new NullPointerException("columnHeaders was null...");
			return (String) columnHeaders[i];
		}

		public Class getColumnClass(int i) {
			if (columnClasses == null)
				throw new NullPointerException("columnClasses was null..");
			return columnClasses[i];
		} /*
		   * (non-Javadoc)
		   * 
		   * @see javax.swing.table.TableModel#getRowCount()
		   */

		public int getRowCount() {
			if (data == null)
				return 0;
			return data.length;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#getColumnCount()
		 */
		public int getColumnCount() {
			// TODO Auto-generated method stub
			if (data == null || data[0] == null)
				return 0;
			return data[0].length;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#getValueAt(int, int)
		 */
		public Object getValueAt(int arg0, int arg1) {
			// TODO Auto-generated method stub
			if (data == null || data[arg0] == null || data[arg0][arg1] == null)
				return null;
			return data[arg0][arg1];
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int,
		 *      int)
		 */
		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
			if (columnIndex == 0) //Don't update PK Column ...
				return;
			data[rowIndex][columnIndex] = aValue;
			fireTableCellUpdated(rowIndex, columnIndex);
		}
	}
}

Code:
mysql> create table user (id int primary key auto_increment, username varchar(32), password varchar(32), admin bool);
Query OK, 0 rows affected (0.29 sec)

mysql> insert into user (username,password,admin) values('tom','dddada',true);
Query OK, 1 row affected (0.06 sec)

mysql> insert into user (username,password,admin) values('fritz','waddehadde',false);
Query OK, 1 row affected (0.00 sec)

mysql> insert into user (username,password,admin) values('dieter','pups',false);
Query OK, 1 row affected (0.00 sec)

Gruß Tom
 
Hallo!

Auf besonderen Wunsch hin das ganze als seperate Klassen:

Code:
/*
 * Created on 10.12.2004@23:29:27
 *
 * TODO Explain me ...
 */
package de.tutorials;

import java.awt.Container;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

/**
 * @author Darimont
 *  
 */
public class JTableExample extends JFrame {

	private Connection con;

	private JTable table;

	private DBAwareTableModel model;

	public JTableExample() {
		super("JTableExample");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		Container c = getContentPane();
		table = new JTable();
		c.add(new JScrollPane(table));
		pack();

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				try {
					if (JTableExample.this.con != null
							&& !JTableExample.this.con.isClosed()) {
						System.out
								.println("Trying to close the remaining Connection...");
						JTableExample.this.con.close();
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		});

		setVisible(true);

	}

	public static void main(String[] args) {
		new JTableExample().start();
	}

	/**
	 *  
	 */
	private void start() {
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			MysqlDataSource ds = new MysqlDataSource();
			ds.setDatabaseName("test");
			ds.setUser("root");
			ds.setPassword("");
			ds.setServerName("localhost");
			ds.setPort(3306);

			con = (Connection) ds.getConnection();
			populateTable("SELECT id, username,password, admin FROM user");
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	/**
	 * @param string
	 */
	private void populateTable(String sql) throws SQLException {
		// TODO Auto-generated method stub
		if (con == null)
			throw new NullPointerException("con was null...");
		Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
				ResultSet.CONCUR_UPDATABLE);

		model = new DBAwareTableModel(stmt.executeQuery(sql));
		table.setEnabled(false);
		table.setModel(model);
		table.updateUI();
		table.setEnabled(true);
	}

}

Code:
/*
 * Created on 12.12.2004@20:19:47
 *
 * TODO Explain me ...
 */
package de.tutorials;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

/**
 * @author Darimont
 *  
 */
class DBAwareTableModel extends AbstractTableModel {

	private final String pkColumnName = "ID";

	private Object[][] data;

	private Object[] columnHeaders;

	private Class[] columnClasses;

	private ResultSet rs;

	public DBAwareTableModel(ResultSet rs) {
		if (rs == null)
			throw new NullPointerException("rs was null!");
		this.rs = rs;
		try {

			ResultSetMetaData rsmd = rs.getMetaData();
			int clmnCnt = rsmd.getColumnCount();
			columnHeaders = new Object[clmnCnt];
			columnClasses = new Class[columnHeaders.length];
			try {
				for (int i = 1; i <= clmnCnt; i++) {
					columnHeaders[i - 1] = rsmd.getColumnName(i);
					columnClasses[i - 1] = Class.forName(rsmd
							.getColumnClassName(i));
				}
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
			}

			List rows = new ArrayList();
			while (rs.next()) {
				Object[] row = new Object[clmnCnt];
				for (int i = 1; i <= clmnCnt; i++) {
					row[i - 1] = rs.getObject(i);
				}
				rows.add(row);
			}

			data = new Object[rows.size()][];
			for (int i = 0; i < data.length; i++) {
				data[i] = (Object[]) rows.get(i);
			}

			//rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.table.TableModel#isCellEditable(int, int)
	 */
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		// TODO Auto-generated method stub

		if (getColumnName(columnIndex).equals(pkColumnName))
			return false;
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.table.AbstractTableModel#fireTableCellUpdated(int, int)
	 */
	public void fireTableCellUpdated(int row, int column) {
		if (rs == null)
			throw new NullPointerException("con was null...");
		try {

			rs.first();
			rs.absolute(row + 1);

			rs.updateObject(column + 1, getValueAt(row, column));
			rs.updateRow();
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	public String getColumnName(int i) {
		if (columnHeaders == null || columnHeaders[i] == null)
			throw new NullPointerException("columnHeaders was null...");
		return (String) columnHeaders[i];
	}

	public Class getColumnClass(int i) {
		if (columnClasses == null)
			throw new NullPointerException("columnClasses was null..");
		return columnClasses[i];
	} /*
	   * (non-Javadoc)
	   * 
	   * @see javax.swing.table.TableModel#getRowCount()
	   */

	public int getRowCount() {
		if (data == null)
			return 0;
		return data.length;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.table.TableModel#getColumnCount()
	 */
	public int getColumnCount() {
		// TODO Auto-generated method stub
		if (data == null || data[0] == null)
			return 0;
		return data[0].length;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.table.TableModel#getValueAt(int, int)
	 */
	public Object getValueAt(int arg0, int arg1) {
		// TODO Auto-generated method stub
		if (data == null || data[arg0] == null || data[arg0][arg1] == null)
			return null;
		return data[arg0][arg1];
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
	 */
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		if (columnIndex == 0) //Don't update PK Column ...
			return;
		data[rowIndex][columnIndex] = aValue;
		fireTableCellUpdated(rowIndex, columnIndex);
	}
}

Gruß Tom
 
Hallo,

diese Thematik ist ansich zwar ziemlich speziell aber dennoch sehr oft benötigt. Tom´s Ausführungen eignen sich hervorragend als Tutorial zum Manipulieren von Daten in Datenbanken mittels gewöhnlichen Swing Komponenten - so einfach kann es sein.

Meines Erachtens sollte dieses "Tutorial" unbedingt auch als solches unter tutorials.de zu finden sein - mir hat es unheimlich geholfen!

Danke bloddy
 
Zurück