# JTable bei Insert in DB via jdbc aktualisieren



## Guest (15. Dez 2008)

Hallo,

ich stehe vor folgendem Problem: Ich habe eine JTable und ein dazughöriges TableModel. Die Tabelle wird mir wunderbar angezeigt. Die Daten hole ich via JDBC aus einer Datenbank.
Füge ich nun ebenfalls via JDBC einen Datensatz in die DB ein, möchte ich auch die JTable aktualisieren. Nur klappt das nicht bzw. ich weiß noch nicht, wie ich das anstellen soll. Den relevanten Code poste ich mal hier... Es wäre schön, wenn mir jemand helfen könnte. 

Zudem würde ich gerne wissen, wo der Unterschied zwischen 





> implements TableModel


 und 





> extends AbstractTableModel


 liegt. Am besten mal mit eigenen Worten erklärt und nicht allzu abstrakt. Wo genau muss ich dabei das DefaultTableModel einordnen?

Kann ich auch mittels der setValueAt-Methode des Models Daten via JDBC in die DB schreiben? Wäre das evtl. sogar die ideale Lösung? Wie würde das funktionieren?

Vielen Dank schonmal, Carsten


* Methoden in der Klasse Mitarbeitererfassung*

```
private void setMitarbeiter() {
		
		try {
	    	con = DBConn.openDB();			
		    System.out.println("Connection Successful ");
	    } catch (Exception e) {	    	
	    	e.printStackTrace();
	    	System.out.println("Keine Verbindung zur Datenbank");
	    }
	    try {

	    	java.sql.Date gebdatesql = null;
	    	
	    	try {
	    		java.util.Date gebdate = new java.util.Date();
	    		DateFormat df;
	    		df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMANY);	    		
	    		gebdate = df.parse(geburtsdatum.getText());
		    	gebdatesql = new java.sql.Date(gebdate.getTime());	    			    		
	    		
	    	} catch (ParseException pe) {
	    		pe.printStackTrace();
	    	}

	    	PreparedStatement speicherMitarbeiter = con.prepareStatement( 
	    	  "INSERT into PERSONAL (Nachname,Vorname,Position,Geburtsdatum,Einstellungsdatum,Straße,PLZ,Ort,[Telefon privat]) values (?,?,?,?,?,?,?,?,?)");
	    	System.out.println(nachname.getText());
	    	speicherMitarbeiter.setString( 1, nachname.getText() ); 
	    	speicherMitarbeiter.setString( 2, vorname.getText() );
	    	speicherMitarbeiter.setString( 3, position.getText() );	    	
	    	speicherMitarbeiter.setDate( 4, gebdatesql );
	    	speicherMitarbeiter.setDate( 5, gebdatesql );
	    	speicherMitarbeiter.setString( 6, strasse.getText() );
	    	speicherMitarbeiter.setString( 7, plz.getText() );
	    	speicherMitarbeiter.setString( 8, ort.getText() );
	    	speicherMitarbeiter.setString( 9, telpriv.getText() );
	    	speicherMitarbeiter.executeUpdate();
	    	System.out.println(speicherMitarbeiter.toString());
	    	
	    	speicherMitarbeiter.close();
	    	con.close();
	    	System.out.println("Datenbankverbindung getrennt");
	    	speicherMitarbeiter.close();
	    	con.close();
	    	
	    	
	    		    		    	
	    	
	    }catch (Exception e) {
	    	e.printStackTrace();
	    }
	
	}
```



```
private JScrollPane tabelleAnzeigen()  {

		//Vector<String> columnNames = new Vector<String>(); // so wars vorher, nacher Object!!!
		Vector<Object> columnNames = new Vector<Object>();
	    Vector<Vector<Object>> data = new Vector<Vector<Object>>();
		
	    try {
	    	con = DBConn.openDB();			
		    System.out.println("Connection Successful ");
	    } catch (Exception e) {	    	
	    	e.printStackTrace();
	    	System.out.println("Keine Verbindung zur Datenbank");
	    }
		
	    try {
	    	String query = "SELECT * from Personal";
	    	Statement stmt = con.createStatement();
	    	ResultSet rst = stmt.executeQuery(query);
	    	ResultSetMetaData md = rst.getMetaData();
	    	int columns = md.getColumnCount();	    	
            for (int i = 1; i <= columns; i++) {
                String colname=md.getColumnName(i);
                columnNames.addElement( colname );
            }
            while (rst.next()) {
                Vector<Object> row = new Vector<Object>(columns);
                for (int i = 1; i <= columns; i++) {
                    row.addElement( rst.getObject(i) );
                }
                data.addElement( row );
            }
            rst.close();
            stmt.close();
            
	    }catch (Exception e2) {
	    	e2.printStackTrace();
	    }
	    table = new JTable();
	    model = new maModel (data, columnNames);
	    table.setModel(model);
	    scrollTabelle = new javax.swing.JScrollPane();
	    scrollTabelle.setViewportView(table);
	     
	    return scrollTabelle;

	}
```

*Das dazughörige Model*



```
package components;

import java.util.Vector;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class maModel implements TableModel {

	private static final long serialVersionUID = 8823887607183509554L;
	private Vector<TableModelListener> listeners = new Vector<TableModelListener>(); 
	private Vector<Vector<Object>> dataEntries = new Vector<Vector<Object>>(); 
	private Vector<Object> columnidentifier = new Vector<Object>(); 
	
	public maModel (Vector<Vector<Object>> dataEntries, Vector<Object> columnidentifier) {
        this.dataEntries = dataEntries;
        this.columnidentifier = columnidentifier;
    }
	
	public void addTableModelListener(TableModelListener l) {
        listeners.add(l);
    }
    public void removeTableModelListener(TableModelListener l) {
        listeners.remove(l);
    }
    public Class<?> getColumnClass(int columnIndex) {
        return String.class;
    }
    public int getColumnCount() {
        return columnidentifier.size();
    }
    public String getColumnName(int columnIndex) {
        return columnidentifier.get(columnIndex).toString();
    }
    public int getRowCount() {
        return dataEntries.size();
    } 
    
    public Object getValueAt(int rowIndex, int columnIndex) {
        Vector<Object> temp = dataEntries.get(rowIndex);
        return temp.get(columnIndex);
    }
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        Vector<Object> temp = dataEntries.get(rowIndex);
        temp.set(columnIndex, value);
    }
    public void addRow(Vector<Object> row) {
        dataEntries.add(row);
    }
    public void setColumnidentifier(Vector<Object> columnidentifier) {
        this.columnidentifier = columnidentifier;
    } 
    
    public void addTimeColumn(Vector<Object> column) {
        for (int i = 0; i < column.size(); ++i) {
            Vector<Object> temp = new Vector<Object>();
            temp.add(column.get(i));
            addRow(temp);
        }
    } 
    
    public void addColumn(String identifier, Vector<Object> column) {
        columnidentifier.add(identifier);
        int index = dataEntries.get(0).size();
        for (int i = 0; i < dataEntries.size(); ++i) {
            dataEntries.get(i).add(index, column.get(i));
        }
        fireTableStructureChanged();
    }
    
    public void fireTableStructureChanged() {
        fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
    } 
    
    public void fireTableChanged(TableModelEvent e){
        for (int i = 0, n = listeners.size(); i < n; i++) {
            ((TableModelListener) listeners.get(i)).tableChanged(e);
        }
    }
   	
}
```


----------



## Guest (17. Dez 2008)

Hi,

wow, dass passt so ungefähr auf mein aktuelles Problem. Zwar nur so unegfähr, aber die Lösung hierzu würde mir denke ich schon weiterhelfen.

Also freue ich mich zusammen mit dem anonymen User (Gast) auf viele viele Antworten!

Grüße, Bernd


----------



## SlaterB (17. Dez 2008)

@Bernd:
nicht einfach so antworten, dein Beitrag bringt fast nix und als erste Antwort streichst du den Thread von der wichtigen Liste 'Unbeantwortete Themen'


------

zu den ersten Fragen:
http://www.java-forum.org/de/viewtopic.php?p=476822

> Kann ich auch mittels der setValueAt-Methode des Models Daten via JDBC in die DB schreiben? 

genau dann, wenn das TableModel sowas anbietet,
ein Standard-Model in der API gibts dafür nicht,
wenn dann nur in externen zusätzlichen Libraries,

kurze google-Suche führte zu
http://forums.sun.com/thread.jspa?threadID=5141966
(edit: nachdem ich reingeschaut habe: diese Art des Durcheinanders von JDBC und Swing kann ich aber nicht gutheißen)

> Füge ich nun ebenfalls via JDBC einen Datensatz in die DB ein, möchte ich auch die JTable aktualisieren. Nur klappt das nicht bzw. ich weiß noch nicht, wie ich das anstellen soll. 

genau zum Zeitpunkt des Inserts auch das Model aktualisieren,

wenn du noch nicht ein TableModel um einen Eintrag erweitern kannst, dann ist das ein Thema für sich,
hat dann mit dem DB-Insert eher wenig zu tun 
(falls es dennoch genau die Frage ist, bitte bestätigen + vielleicht etwas näher ausführen)


----------



## bernds (17. Dez 2008)

@Slater: Vielen Dank. Das mit den verschiedenen Models habe ich jetzt denke ich grundsätzlich verstanden.

Zur anderen Sache: Habe mein Model nun mal ein wenig angepasst und erweitert (Die JTable ist nun auch editierbar). Jedoch funktioniert das immer noch nicht so ganz. Wenn ich die Tabelle im Programm editiere erhalte ich einen Fehler (siehe unten angefügt). Kann mir evtl. jemand sagen, wo genau nun das Problem ist und wie ich das Model irgendwie so sauber hinbekomme, dass es funktioniert? 
Das mit dem Update des Models nach dem Insert bekomme ich dann mit Sicherheit auch allein hin, wenn das nun funktionieren würde.

Vielen Dank

*Model*

```
package components;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

// implements TableModel sollte auch gehen.
public class maModel extends AbstractTableModel implements TableModelListener{

	private static final long serialVersionUID = 8823887607183509554L;
	private Vector<TableModelListener> listeners = new Vector<TableModelListener>(); 
	private Vector<Vector<Object>> dataEntries = new Vector<Vector<Object>>(); 
	private Vector<Object> columnidentifier = new Vector<Object>(); 
	
	private static Connection con;
	
	public maModel (Vector<Vector<Object>> dataEntries, Vector<Object> columnidentifier) {
        this.dataEntries = dataEntries;
        this.columnidentifier = columnidentifier;
    }
	
	public void addTableModelListener(TableModelListener l) {
        listeners.add(l);
    }
    public void removeTableModelListener(TableModelListener l) {
        listeners.remove(l);
    }
    public Class<?> getColumnClass(int columnIndex) {
        return String.class;
    }
    public int getColumnCount() {
        return columnidentifier.size();
    }
    public String getColumnName(int columnIndex) {
        return columnidentifier.get(columnIndex).toString();
    }
    public int getRowCount() {
        return dataEntries.size();
    } 
    
    public Object getValueAt(int rowIndex, int columnIndex) {
        Vector<Object> temp = dataEntries.get(rowIndex);
        return temp.get(columnIndex);
    }
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        Vector<Object> temp = dataEntries.get(rowIndex);
        temp.set(columnIndex, value);
        tableChanged(new TableModelEvent(this, TableModelEvent.UPDATE));
    }
    public void addRow(Vector<Object> row) {
        dataEntries.add(row);
    }
    public void setColumnidentifier(Vector<Object> columnidentifier) {
        this.columnidentifier = columnidentifier;
    } 
    
    public void addTimeColumn(Vector<Object> column) {
        for (int i = 0; i < column.size(); ++i) {
            Vector<Object> temp = new Vector<Object>();
            temp.add(column.get(i));
            addRow(temp);
        }
    } 
    
    public void addColumn(String identifier, Vector<Object> column) {
        columnidentifier.add(identifier);
        int index = dataEntries.get(0).size();
        for (int i = 0; i < dataEntries.size(); ++i) {
            dataEntries.get(i).add(index, column.get(i));
        }
        fireTableStructureChanged();
    }
    
    public void fireTableStructureChanged() {
        fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
    } 
    
    public void fireTableChanged(TableModelEvent e){
        for (int i = 0, n = listeners.size(); i < n; i++) {
            ((TableModelListener) listeners.get(i)).tableChanged(e);
        }
    }
    
    public void tableChanged(TableModelEvent evt) {
        if (evt.getType() == TableModelEvent.UPDATE) {
            int column = evt.getColumn();
            int row = evt.getFirstRow();
            String newValue = this.getValueAt(row,column).toString();
                       
            try {
				con = DBConn.openDB();
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}            
			
            try {
                if(con!=null){
                    Statement stmt = con.createStatement();
                    String UpdateStmt = "UPDATE Personal SET"+getColumnName(column)+"='"+newValue+"' WHERE personal-nr='"+this.getValueAt(row, column)+"'";
                    System.out.println(UpdateStmt);
                    JOptionPane.showMessageDialog( null, UpdateStmt );                  
                    stmt.close();
                    con.close();
                }
            } catch (SQLException sqe) {
                String message = sqe.getMessage();
                if(message.contains(":")){
                    message = message.substring( message.indexOf(":") + 1 );
                }
                JOptionPane.showMessageDialog( null, message );
            }
        }
    }
   	
}
```

*Die Exception*



> Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
> at java.util.Vector.get(Unknown Source)
> at components.maModel.getValueAt(maModel.java:49)
> at components.maModel.tableChanged(maModel.java:97)
> ...


[/code]


----------



## SlaterB (17. Dez 2008)

der Fehler ist offensichtlich, dass
> evt.getFirstRow()
-1 ergibt

weil 
> new TableModelEvent(this, TableModelEvent.UPDATE)
es vielleicht nicht besser erzeugt,
warum genau kann ich da im Moment nicht weiter nachforschen,

kannst ja morgen am Tag nochmal posten, wenn dann noch aktuell,
vielleicht kann ich dann genauer nachschauen


----------



## bernds (17. Dez 2008)

Hallo, 

ja das ist morgen noch aktuell, da ich auch erst morgen gegen Abend dazu kommen werde, mich der Sache wieder zu widmen. Von daher wäre es super, wenn mir jemand konkret meinen Fehler evtl. sogar mit ner Lösung aufzeigen könnte. Das würde mir das Weihnachtsfest versüßen...

Bis dahin und Danke!


----------



## SlaterB (18. Dez 2008)

tja, also der Konstruktor, den du verwendest, ist:


```
/**
     *  This row of data has been updated. 
     *  To denote the arrival of a completely new table with a different structure 
     *  use <code>HEADER_ROW</code> as the value for the <code>row</code>. 
     *  When the <code>JTable</code> receives this event and its
     *  <code>autoCreateColumnsFromModel</code> 
     *  flag is set it discards any TableColumns that it had and reallocates 
     *  default ones in the order they appear in the model. This is the 
     *  same as calling <code>setModel(TableModel)</code> on the <code>JTable</code>. 
     */
    public TableModelEvent(TableModel source, int row) {
	this(source, row, row, ALL_COLUMNS, UPDATE);
    }
```

> tableChanged(new TableModelEvent(this, TableModelEvent.UPDATE)); 


TableModelEvent.UPDATE ist schon mal falsch gewählt, das kommt als row an (int-Wert 0), 
column ist gar nicht angegeben, deshalb wird dafür ALL_COLUMNS eingesetzt, welches -1 ist

kein Wunder, dass getValueAt() dabei durchdreht


----------



## bernds (20. Dez 2008)

Vielen Dank,

aber irgendiwe bin ich ein wenig verwirrt. Wie mach ich es denn richtig?

Grüße und danke


----------



## SlaterB (20. Dez 2008)

was ist 'es'?
denkbar wäre z.B., einen Konstruktor mit richtigen row + column -Parametern zu verwenden


----------



## Gast (20. Dez 2008)

Habs jetzt hinbekommen. Nochmal viele Dank!!!


----------

