# Java Abfrage über GUI, Daten hinzufügen



## NichtExpert (11. Mrz 2020)

Hallo,
ich will wie als Überschrift erwähnt, eine zeile in meiner Gui im Table der SQL Datenbank hinzufügen.
Dazu habe ich mir einen button erstellt, der auf knopfdruck eine zeile hinzufügen soll.
Den button habe ich erstellt, Frage ist, ob der Ansatz so richtig ist:

JButton btnadd = new JButton("Zeile hinzufügen");                           //Button hinzugefügt
btnadd.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
    model.addRow(Object[] );                                    // IST DIESER ANSATZ RICHTIG???
    }
});
btnadd.setBounds(197, 180, 129, 23 );
getContentPane().add(btnadd);


----------



## lam_tr (11. Mrz 2020)

Ja prinzipiell spricht nichts dagegen oder? Ich hätt das auch so gemacht, eventuell noch in ein UIThread gepackt damit, die UI nicht einfriert wenn das Insert nicht auf Anhieb klappt.


----------



## NichtExpert (11. Mrz 2020)

In den geschweiften Klammern bei "model.addRow()" das object[] habe ich nicht im Code vorhanden. Verweise ich dort jetzt auf die Tabelle?


----------



## lam_tr (11. Mrz 2020)

NichtExpert hat gesagt.:


> In den geschweiften Klammern bei "model.addRow()" das object[] habe ich nicht im Code vorhanden. Verweise ich dort jetzt auf die Tabelle?


Wie greifst du auf die Datenbank?


----------



## NichtExpert (11. Mrz 2020)

lam_tr hat gesagt.:


> Wie greifst du auf die Datenbank?


Ähhmmm, ich schicke mal den Code


```
package Test_sql;

import datenbank.SQL_GUI_Connection_personalie;

import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Test_Daten_hinzufügen extends JFrame {

    /**
     * Launch the application
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test_Daten_hinzufügen frame = null;
                try {
                    frame = new Test_Daten_hinzufügen();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                frame.setVisible(true);                                                                                 // Frame sichtbar
            }
        });
    }

    /**
     * Create the Frame
     */
    public Test_Daten_hinzufügen() throws SQLException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                                                                 // Run beenden
        setBounds(100, 100, 580, 242 );                                                            // Frame größe
        setTitle("Tutorial-Beispiel");                                                                                  // Frame Überschrift
        getContentPane().setLayout(null);

        /**
         * Scrollpane
         */
        JScrollPane scrollPane = new JScrollPane();                                                                     // ScrollPane erstellt
        scrollPane.setBounds(64, 44, 440, 89);                                                      // Größe Scrollpane
        getContentPane().add(scrollPane);                                                                               // Scrollpane dem getContentpane hinzugefügt

        /**
         * Table
         */
        JTable table = new JTable();                                                                                    // Table erstellt
        scrollPane.setViewportView(table);                                                                              // scrollpane dem table (tabelle) hinzugefügt

        /**
         * Model für Table
         */
        DefaultTableModel model = (DefaultTableModel)table.getModel();                                                  // Model erstellt
        model.addColumn("ID");                                                                            // Überschrift Table (tabelle-spalten)
        model.addColumn("Firstname");                                                                     // Überschrift table (tabelle-spalten)
        model.addColumn("Lastname");                                                                      // Überschrift table (tabelle-spalten)
        model.addColumn("Sport");                                                                         // Überschrift table (tabelle-spalten)
        model.addColumn("# of years");                                                                    // Überschrift table (tabelle-spalten)
        model.addColumn("vegetarian");                                                                    // Überschrift table (tabelle-spalten)


        JLabel lblFilter = new JLabel("Filter :");                                                                 // label erstellt
        lblFilter.setBounds(158, 147, 72, 14);                                                      // Label Größe
        getContentPane().add(lblFilter);                                                                                // label dem getContentPane zugeordnet

        /**
         * Filter
         */
        final JTextField txtFilter = new JTextField();                                                                  // Textfield erstellt
        txtFilter.setBounds(197, 144, 129, 20);                                                     // Textfield erstellt
        getContentPane().add(txtFilter);                                                                                // Textfielf dem GetContentpane zugeordnet

        /**
         * Header Sort
         */
        final TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
        table.setRowSorter(sorter);

        /**
         * Filter-Button  (OK-Button)
         */
        JButton btnOK = new JButton("OK");                                                                         // button erstellt, Button-Schrift="OK"
        btnOK.addActionListener(new ActionListener() {                                                                  // Befehl, click auf button hinzugefügt
            @Override                                                                                                   //
            public void actionPerformed(ActionEvent actionEvent) {                                                      //
                String expr = txtFilter.getText();                                                                      // String expr = textfield (bekommt text von dort)
                sorter.setRowFilter(RowFilter.regexFilter(expr));                                                       //
                sorter.setSortKeys(null);                                                                               //
            }
        });
        btnOK.setBounds(336, 144, 59, 23);                                                          // Button Größe
        getContentPane().add(btnOK);                                                                                    // Button dem getContnetPane zugeordnet
/**
 * *********************************************************************************************************************
 */
        JButton btnadd = new JButton("Zeile hinzufügen");
        btnadd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
            model.addRow();                                    // IST DIESER ANSATZ RICHTIG???
            }
        });
        btnadd.setBounds(197, 180, 129, 23 );
        getContentPane().add(btnadd);

/**
 * *********************************************************************************************************************
  */
        Connection connect = null;
        Statement s = null;

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");                                                                  // SQL Treiber

            connect = DriverManager.getConnection("jdbc:mysql://localhost/test","till","Tillerni02");     // Connection zur Datenbank (Pfad + nutzername + passwort der Datenbank)

            s = connect.createStatement();

            String sql = "SELECT * FROM personalie ORDER BY ID";                                                        // Auswahl Tabelle, Anzeigekriterien

            ResultSet rec = s.executeQuery(sql);
            int row = 0;
            while ((rec!=null) && (rec.next()))
            {
                model.addRow(new Object[0]);
                model.setValueAt(rec.getString("ID"), row, 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Firstname"), row, 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Lastname"), row, 2);                                         // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Sport"), row, 3);                                            // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getFloat("# of years"), row, 4);                                        // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("vegetarian"), row, 5);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                row++;
            }

            rec.close();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            JOptionPane.showMessageDialog(null, e.getMessage());
            e.printStackTrace();
        }


        try {
            if (s != null) {
                s.close();
                connect.close();
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
```


----------



## lam_tr (11. Mrz 2020)

NichtExpert hat gesagt.:


> Ähhmmm, ich schicke mal den Code
> 
> 
> ```
> ...


Ich kenne mich ehrlich gesagt mit Swing nicht viel aus, aber dem Code nach von dieser Seite https://stackoverflow.com/questions/3549206/how-to-add-row-in-jtable, kann ich über diesen Weg realisieren.


```
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(new Object[]{"Column 1", "Column 2", "Column 3"});
```

Das entspricht immer eine Zeile im JTable.

Das mit dem Zeile hinzufügen ist damit Datenbank oder JTable gemeint?

Für Datenbank würde ich ein PreparedStatement mit dem INSERT SQL machen, siehe hier


			JDBC PreparedStatement – Insert a row – Mkyong.com
		

.


----------



## NichtExpert (12. Mrz 2020)

lam_tr hat gesagt.:


> Das mit dem Zeile hinzufügen ist damit Datenbank oder JTable gemeint?


Geplant war, dass sich die zeile in der Datenbank als auch in der GUI aktualisiert.


----------



## NichtExpert (12. Mrz 2020)

Also eine zelle in der GUI sprich JTable aktualisiert sich die zeile. Ich schicke mal den Code mit, damit Anfänger, falls sie auf diesen Thread stoßen wissen was ich getan habe.

```
JButton btnadd = new JButton("Zeile hinzufügen");
        btnadd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
            model.addRow(new Object[] {});                                    // Es wird eine zeile (addRow) hinzugefügt ohne Daten (steht in der "{}")
            }
        });
        btnadd.setBounds(336, 180, 129, 23 );
        getContentPane().add(btnadd);
```


----------



## lam_tr (12. Mrz 2020)

NichtExpert hat gesagt.:


> Also eine zelle in der GUI sprich JTable aktualisiert sich die zeile. Ich schicke mal den Code mit, damit Anfänger, falls sie auf diesen Thread stoßen wissen was ich getan habe.
> 
> ```
> JButton btnadd = new JButton("Zeile hinzufügen");
> ...



Also die Zeile von dir erstelt eine Zeile im JTable, aber ohne Daten. Je nachdem wieviele Spalten du hast, muss du noch Werte in das Array setzen.



NichtExpert hat gesagt.:


> Geplant war, dass sich die zeile in der Datenbank als auch in der GUI aktualisiert.


Dafür beötigst du dann einen Service der die Connection öffnet, schließt und insert vorbereitet. 

Bleibst du irgendwo stecken?


----------



## NichtExpert (12. Mrz 2020)

lam_tr hat gesagt.:


> Dafür beötigst du dann einen Service der die Connection öffnet, schließt und insert vorbereitet.
> 
> Bleibst du irgendwo stecken?


Funktioniert, nur füge ich momentan nur Daten zum JTable hinzu, jetzt muss noch GUI gemacht werden


----------



## NichtExpert (12. Mrz 2020)

lam_tr hat gesagt.:


> Also die Zeile von dir erstelt eine Zeile im JTable, aber ohne Daten. Je nachdem wieviele Spalten du hast, muss du noch Werte in das Array setzen.


Versucht habe ich auch, die Spalte ID, automatsich um 1 zu erhöhen. also von der letzten ID zahl.
Rausgekommen ist aber nur ein Integer wert, den ich auf die nächste ID-zahl gesetzt habe und dann ID++


```
final int[] ID = {6}; // In der Datenbank gibt es momentan nur 5 Zeilen (bis Id zahl 5)

        JButton btnadd = new JButton("Zeile hinzufügen");
        btnadd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
            model.addRow(new Object[] {ID[0]++}); // fügt zeile hinzu und setzt ID auf 6, danach immer ++ (7, 8, 9, ...)                                   // { textField.getText }
            }                                                                        //  { ID[0]++ }  (integer zahl auf 6 gesetzt, addiert dann immer die Zahl um 1)
        });
        btnadd.setBounds(336, 180, 129, 23 );
        getContentPane().add(btnadd);
```


----------



## lam_tr (12. Mrz 2020)

Alles klar, viel Spaß.


----------



## NichtExpert (12. Mrz 2020)

Irgendwie klappt es nicht. Aber im Grunde genommen mache ich doch nur eine neue try...catch:

```
try {
            Class.forName("com.mysql.cj.jdbc.Driver");                                                                  // SQL Treiber

            connect = DriverManager.getConnection("jdbc:mysql://localhost/test","test","test");     // Connection zur Datenbank (Pfad + nutzername + passwort der Datenbank)

            s = connect.createStatement();

            String sql = "SELECT * FROM personalie ORDER BY ID";                                                        // Auswahl Tabelle, Anzeigekriterien


            ResultSet rec = s.executeQuery(sql);
             int row = 0;
            while ((rec!=null) && (rec.next()))
            {
                model.addRow(new Object[0]);
                model.setValueAt(rec.getString("ID"), row, 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Firstname"), row, 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Lastname"), row, 2);                                         // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Sport"), row, 3);                                            // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getFloat("# of years"), row, 4);                                        // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("vegetarian"), row, 5);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                row++;


            }

            rec.close();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            JOptionPane.showMessageDialog(null, e.getMessage());
            e.printStackTrace();
        }



        try {
            if (s != null) {
                s.close();
                connect.close();
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
```

und füge dort meine "SQL_INSERT" -Anweisung durch. Oder fehlt mir noch was ganz entscheidenes?


----------



## lam_tr (12. Mrz 2020)

NichtExpert hat gesagt.:


> Irgendwie klappt es nicht. Aber im Grunde genommen mache ich doch nur eine neue try...catch:
> 
> ```
> try {
> ...



Was bekommst du wenn du das hier machst


```
while ((rec!=null) && (rec.next()))
            {
                model.addRow(new Object[]{rec.getString("ID"),rec.getString("Firstname"), rec.getString("Lastname"), ....});
                row++;
            }
```


----------



## NichtExpert (12. Mrz 2020)

lam_tr hat gesagt.:


> Was bekommst du wenn du das hier machst


Soll ich das durch :

```
while ((rec!=null) && (rec.next()))
            {
                model.addRow(new Object[0]);
                model.setValueAt(rec.getString("ID"), row, 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Firstname"), row, 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Lastname"), row, 2);                                         // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Sport"), row, 3);                                            // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getFloat("# of years"), row, 4);                                        // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("vegetarian"), row, 5);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                row++;
```
ersetzen oder darunter hinzufügen?


----------



## lam_tr (13. Mrz 2020)

den Inhalt in der While Schleife ersetzen ja.


----------



## NichtExpert (16. Mrz 2020)

Ich bekomme immer wieder eine Fehlermeldung:
java.sql.SQLException: Operation not allowed after ResultSet closed

Auch wenn ich 

```
rec.close();
```
weg mache.

Ich schätze mal es liegt an dem Teil:

```
while ((rec!=null) && (rec.next())) {
```
?


----------



## lam_tr (16. Mrz 2020)

An welcher Stelle wird die Exception geworfen im StackTrace?


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> An welcher Stelle wird die Exception geworfen im StackTrace?




```
An der stelle sollte es geworfen werden:
model.addRow(new Object[]{rec.getString("ID"), rec.getString("Firstname"), rec.getString("Lastname"), rec.getString("Sport"), rec.getString("# of years"), rec.getString("Vegetarian")});
```


----------



## thecain (16. Mrz 2020)

Heisst die Spalte wirklich "# of years"?


----------



## lam_tr (16. Mrz 2020)

Zeig mir mal den Stacktrace Ausdruck bitte. Und ich weiß nicht ob du Null Werte in das Modell übergeben kannst. Geben alle Aufrüfe etwas zurück?


----------



## NichtExpert (16. Mrz 2020)

thecain hat gesagt.:


> Heisst die Spalte wirklich "# of years"?


Bescheuert ich weiß,umbenennen geht immer


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Zeig mir mal den Stacktrace Ausdruck bitte.




```
java.sql.SQLException: Operation not allowed after ResultSet closed
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
    at com.mysql.cj.jdbc.result.ResultSetImpl.checkClosed(ResultSetImpl.java:437)
    at com.mysql.cj.jdbc.result.ResultSetImpl.findColumn(ResultSetImpl.java:544)
    at com.mysql.cj.jdbc.result.ResultSetImpl.getString(ResultSetImpl.java:852)
    at Test_sql.Test_Daten_hinzufügen$3.actionPerformed(Test_Daten_hinzufügen.java:172)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:270)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6651)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6416)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5026)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2773)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
```


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Und ich weiß nicht ob du Null Werte in das Modell übergeben kannst. Geben alle Aufrüfe etwas zurück?


Wenn ich den Teil enthalten lasse:

```
while ((rec!=null) && (rec.next())) {
                model.addRow(new Object[0]);
                model.setValueAt(rec.getString("ID"), row[0], 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Firstname"), row[0], 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Lastname"), row[0], 2);                                         // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Sport"), row[0], 3);                                            // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getFloat("# of years"), row[0], 4);                                        // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("vegetarian"), row[0], 5);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                row[0]++;
            }
```
Gibt er normal die GUI aus, und wenn ich es ausführe, kommt es dann zur Fehlermeldung.

Wenn ich den Teil:

```
model.addRow(new Object[]{rec.getString("ID"), rec.getString("Firstname"), rec.getString("Lastname"), rec.getString("Sport"), rec.getString("# of years"), rec.getString("Vegetarian")});
```
darunter einfüge, dasselbe Spiel.

Wenn ich aber den Teil lösche:
CODE=java]while ((rec!=null) && (rec.next())) {
                model.addRow(new Object[0]);
                model.setValueAt(rec.getString("ID"), row[0], 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Firstname"), row[0], 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Lastname"), row[0], 2);                                         // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Sport"), row[0], 3);                                            // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getFloat("# of years"), row[0], 4);                                        // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("vegetarian"), row[0], 5);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                row[0]++;
            }[/CODE]
und ersetze das durch:

```
model.addRow(new Object[]{rec.getString("ID"), rec.getString("Firstname"), rec.getString("Lastname"), rec.getString("Sport"), rec.getString("# of years"), rec.getString("Vegetarian")});
```
Dann wird der "Run" gestartet ohne Fehlermeldung. Die angezeigte GUI mit Table ist jedoch leer. Liegt logischerweise daran, dass der obige Code-Teil, den ich gestrichen habe, die Daten aus der SQL-Datenbank holt. 
Klicke ich dann in der leeren table auf dem add-Button, kommt die eine Fehlermeldung.


----------



## lam_tr (16. Mrz 2020)

Wenn du im DebugMode die Ganzen Werte ausgeben lässt enthalten die auch etwas?


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Wenn du im DebugMode die Ganzen Werte ausgeben lässt enthalten die auch etwas?


In welchem Code-Stil denn? 
Ich habe eben verschiedene varianten gemacht, wie ich es ausprobiert habe. Welche von denen meinst du genau?


----------



## lam_tr (16. Mrz 2020)

NichtExpert hat gesagt.:


> while ((rec!=null) && (rec.next())) {
> model.addRow(new Object[0]);
> model.setValueAt(rec.getString("ID"), row[0], 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
> model.setValueAt(rec.getString("Firstname"), row[0], 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
> ...



Mir ist gerade das hier aufgefallen, dass du immer row[0] ansprichst und im Anschluss hoch inkrementierst. Macht das einen Sinn, ich verstehe das nicht. Es ist dann immer row[0] oder?


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Es ist dann immer row[0] oder?




Nein, die Tabelle wird wie gewünscht ausgegeben.


----------



## NichtExpert (16. Mrz 2020)

Wenn cih row[0] ändere z.B. zu 1; 2; 3; ...  . Dann kommt es zur fehlermeldung:
 java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1


----------



## lam_tr (16. Mrz 2020)

```
package validator;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

public class Test_Daten_hinzufügen extends JFrame {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * Launch the application
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test_Daten_hinzufügen frame = null;
                try {
                    frame = new Test_Daten_hinzufügen();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                frame.setVisible(true); // Frame sichtbar
            }
        });
    }

    /**
     * Create the Frame
     */
    public Test_Daten_hinzufügen() throws SQLException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Run beenden
        setBounds(100, 100, 580, 242); // Frame größe
        setTitle("Tutorial-Beispiel"); // Frame Überschrift
        getContentPane().setLayout(null);

        /**
         * Scrollpane
         */
        JScrollPane scrollPane = new JScrollPane(); // ScrollPane erstellt
        scrollPane.setBounds(64, 44, 440, 89); // Größe Scrollpane
        getContentPane().add(scrollPane); // Scrollpane dem getContentpane hinzugefügt

        /**
         * Table
         */
        JTable table = new JTable(); // Table erstellt
        scrollPane.setViewportView(table); // scrollpane dem table (tabelle) hinzugefügt

        /**
         * Model für Table
         */
        DefaultTableModel model = (DefaultTableModel) table.getModel(); // Model erstellt
        model.addColumn("ID"); // Überschrift Table (tabelle-spalten)
        model.addColumn("Firstname"); // Überschrift table (tabelle-spalten)
        model.addColumn("Lastname"); // Überschrift table (tabelle-spalten)
        model.addColumn("Sport"); // Überschrift table (tabelle-spalten)
        model.addColumn("# of years"); // Überschrift table (tabelle-spalten)
        model.addColumn("vegetarian"); // Überschrift table (tabelle-spalten)

        JLabel lblFilter = new JLabel("Filter :"); // label erstellt
        lblFilter.setBounds(158, 147, 72, 14); // Label Größe
        getContentPane().add(lblFilter); // label dem getContentPane zugeordnet

        /**
         * Filter
         */
        final JTextField txtFilter = new JTextField(); // Textfield erstellt
        txtFilter.setBounds(197, 144, 129, 20); // Textfield erstellt
        getContentPane().add(txtFilter); // Textfielf dem GetContentpane zugeordnet

        /**
         * Header Sort
         */
        final TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
        table.setRowSorter(sorter);

        /**
         * Filter-Button (OK-Button)
         */
        JButton btnOK = new JButton("OK"); // button erstellt, Button-Schrift="OK"
        btnOK.addActionListener(new ActionListener() { // Befehl, click auf button hinzugefügt
            @Override //
            public void actionPerformed(ActionEvent actionEvent) { //
                String expr = txtFilter.getText(); // String expr = textfield (bekommt text von dort)
                sorter.setRowFilter(RowFilter.regexFilter(expr)); //
                sorter.setSortKeys(null); //
            }
        });
        btnOK.setBounds(336, 144, 59, 23); // Button Größe
        getContentPane().add(btnOK); // Button dem getContnetPane zugeordnet
        /**
         * *********************************************************************************************************************
         */
        JButton btnadd = new JButton("Zeile hinzufügen");
        btnadd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                model.addRow(new Object[] { "Test1", "Test2", "Test3", "Test4", "Test5", "Test6" });
            }
        });
        btnadd.setBounds(197, 180, 129, 23);
        getContentPane().add(btnadd);

        /**
         * *********************************************************************************************************************
         */
    }

}
```

Also das Hinzufügen der Row in die GUI das geht auf jede Fall, das ist nur ein Datenbank Zugriffsproblem. Da ich es selten per Hand mache, muss du mal die DB Pros hier mal nachfragen.

Nachtrag: In dem Beispiel von oracle wird das ResultSet nicht geclosed, sondern direkt das Statement, probier mal damit


			Retrieving and Modifying Values from Result Sets (The Java™ Tutorials >                     JDBC Database Access > JDBC Basics)
		



```
public static void viewTable(Connection con, String dbName)

    throws SQLException {



    Statement stmt = null;

    String query =

        "select COF_NAME, SUP_ID, PRICE, " +

        "SALES, TOTAL " +

        "from " + dbName + ".COFFEES";



    try {

        stmt = con.createStatement();

        ResultSet rs = stmt.executeQuery(query);

        while (rs.next()) {

            String coffeeName = rs.getString("COF_NAME");

            int supplierID = rs.getInt("SUP_ID");

            float price = rs.getFloat("PRICE");

            int sales = rs.getInt("SALES");

            int total = rs.getInt("TOTAL");

            System.out.println(coffeeName + "\t" + supplierID +

                               "\t" + price + "\t" + sales +

                               "\t" + total);

        }

    } catch (SQLException e ) {

        JDBCTutorialUtilities.printSQLException(e);

    } finally {

        if (stmt != null) { stmt.close(); }

    }

}
```


----------



## NichtExpert (16. Mrz 2020)

Wie muss ich das jetzt ändern?


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> finally { if (stmt != null) { stmt.close(); }


Diesen Teil hinten anfügen?


----------



## lam_tr (16. Mrz 2020)

NichtExpert hat gesagt.:


> Diesen Teil hinten anfügen?


Ja genau


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Ja genau


beim Ausführen kommt immernoch die fehlermeldung 

zeile 172, ist die zeile :

```
model.addRow(new Object[]{rec.getString("ID"), rec.getString("Firstname"), rec.getString("Lastname"), rec.getString("Sport"), rec.getString("# of years"), rec.getString("Vegetarian")});
```


----------



## NichtExpert (16. Mrz 2020)

Schätze mit dem Code-Schnipsel stimmt etwas nicht, es wird immer auf ihn verwiesen


----------



## lam_tr (16. Mrz 2020)

Kann es sein dass du Probleme mit dem Zugriff auf die Spalten hast. Versuche doch Spalte für Spalte abzurufen und nicht alle auf einmal.


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Kann es sein dass du Probleme mit dem Zugriff auf die Spalten hast. Versuche doch Spalte für Spalte abzurufen und nicht alle auf einmal.



Es kommt dieselbe Fehlermeldung, ich probier nochmal was...


----------



## NichtExpert (16. Mrz 2020)

NichtExpert hat gesagt.:


> Es kommt dieselbe Fehlermeldung, ich probier nochmal was...


hat nichts gebracht, habe dahinter nochmal   " row[0] "   hinzugefügt.
Als Fehler wird immer

```
model.addRow(new Object[]{rec.getString("ID"), row[0]});
```
gesehen. 
Als alle hintereinander waren, war die gesamte zeile der Fehler

```
model.addRow(new Object[]{rec.getString("ID"), rec.getString("Firstname"), rec.getString("Lastname"), rec.getString("Sport"), rec.getString("# of years
```
jetzt wird die erste zeile von dem hier als Fehler bemängelt

```
model.addRow(new Object[]{rec.getString("ID"), row[0]});
model.addRow(new Object[]{rec.getString("Firstname"), row[0]});
model.addRow(new Object[]{rec.getString("Lastname"), row[0]});
model.addRow(new Object[]{rec.getString("Sport"), row[0]});
model.addRow(new Object[]{rec.getString("# of years"), row[0]});
model.addRow(new Object[]{rec.getString("Vegetarian"), row[0]});
```

bedeutet, an dieser Stelle kommt es zum fehler. und er beendet das Programm


----------



## lam_tr (16. Mrz 2020)

Probiere doch zuerst mal das, bevor du in das model hinzufügst

System.out.println(rec.getString("ID"));
System.out.println(rec.getString("Firstname"));
System.out.println(rec.getString("Lastname"));
...

Schau mal ob der für alle Spalten einen Wert bekommt.


----------



## NichtExpert (16. Mrz 2020)

lam_tr hat gesagt.:


> Probiere doch zuerst mal das, bevor du in das model hinzufügst
> 
> System.out.println(rec.getString("ID"));
> System.out.println(rec.getString("Firstname"));
> ...


Die System.out.println-Methode ist nicht für GUI gedacht. Funktioniert nur in der GUI --> Das weißt du sicherlich.
Bevor ich mit GUI angefangen habe, habe ich natürlich mit der Konsolenausgabe angefangen.


```
package datenbank;

import java.sql.*;

public class MeineErsteAbfrage {

    static Connection con = null;
    static Statement stmt = null;
    static ResultSet rs = null;

    public static void main(String args[]) throws InstantiationException, IllegalAccessException, SQLException {
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
        }
        catch (ClassNotFoundException e){
            e.printStackTrace();
            System.exit(1);
        }
        try{
            con = DriverManager.getConnection
                    ("jdbc:mysql://localhost/film_datenbank","gast","gast");//****** durch pw ersetzen
            stmt=con.createStatement();
            rs=stmt.executeQuery
                    ("SELECT * FROM dvd_sammlung");
            while(rs.next()){
                System.out.println("nr: "+rs.getString(1));
                System.out.println("name: "+rs.getString(2));
                System.out.println("nummer: "+rs.getString(3));
                System.out.println("time (min.): "+rs.getString(4));
                System.out.println("*************************");// optisches trennen der datensätze
            }
            stmt.close();
            con.close();
        }
        catch(SQLException e){
            e.printStackTrace();
            return;
        }
    }
}
```


----------



## lam_tr (16. Mrz 2020)

NichtExpert hat gesagt.:


> Die System.out.println-Methode ist nicht für GUI gedacht. Funktioniert nur in der GUI --> Das weißt du sicherlich.
> Bevor ich mit GUI angefangen habe, habe ich natürlich mit der Konsolenausgabe angefangen.
> 
> 
> ...


Kommen da gescheite Werte beim ausführen raus?


----------



## NichtExpert (16. Mrz 2020)

Funktioniert einwandfrei. es wird auch eine neue zeile erstellt, und auch in die SQL-Datenbank wird eine neue Zeile eingefügt. nur ich will das Ganze in einer GUI im JTable machen. Das ist das große Problem.
Musste auch nur eine Insert zeile hinzufügen

```
int add = stmt.executeUpdate("INSERT INTO dvd_sammlung VALUES ('3', 'Star Wars: Episode IV - Krieg der Sterne', '3', '125')");
            System.out.println(add);
```


----------



## mihe7 (16. Mrz 2020)

Hier mal kurz was zusammengeschustert, nicht schön aber selten:


Spoiler: JdbcTableModel.java





```
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.StringJoiner;
import java.util.List;
import java.util.stream.*;
import java.sql.*;

public class JdbcTableModel extends AbstractTableModel {
    private Connection conn;
    private String query;
    private List<Object[]> data;
    private List<String> columnNames;
    private String tableName;

    public JdbcTableModel(Connection conn, String query) {
        this.conn = conn;
        this.query = query;
        requery();
    }

    public final void requery() {
        data = new ArrayList<>();
        try(Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery(query)) {
            queryColumns(rs);
            while (rs.next()) {
                int cols = getColumnCount();
                Object[] row = new Object[cols+1];
                for (int i = 0; i < cols; i++) {
                    row[i+1] = rs.getObject(i+1);
                }
                data.add(row);
            }
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
    }

    private void queryColumns(ResultSet rs) throws SQLException {
        columnNames = new ArrayList<>();
        ResultSetMetaData rsmd = rs.getMetaData();
        int cols = rsmd.getColumnCount();
        tableName = cols > 0 ? rsmd.getTableName(1) : null;
        for (int i = 0; i < cols; i++) {
            columnNames.add(rsmd.getColumnName(i+1));
        }
    }

    @Override
    public int getColumnCount() { return columnNames.size(); }
    @Override
    public String getColumnName(int ix) { return columnNames.get(ix); }
    @Override
    public int getRowCount() { return data.size(); }
    @Override
    public Object getValueAt(int row, int ix) { return data.get(row)[ix+1]; }
    @Override
    public boolean isCellEditable(int row, int col) { return col >= 0; }

    @Override
    public void setValueAt(Object value, int rowIx, int col) {
        Object[] row = data.get(rowIx);
        row[col+1] = value;
        if (row[0] == null) {
            row[0] = "UPDATE";
        }
        fireTableRowsUpdated(rowIx, rowIx);
    }

    public void insertRow() {
        int cols = getColumnCount();
        int rowIx = data.size();
        Object[] row = new Object[cols+1];
        row[0] = "NEW";
        data.add(row);
        fireTableRowsInserted(rowIx, rowIx);
    }
    public void save() throws SQLException {
        handleInserts();
        handleUpdates();
    }

    private void handleInserts() throws SQLException {
        List<Object[]> toInsert = data.stream()
            .filter(o -> o[0] != null && o[0].equals("NEW"))
            .collect(Collectors.toList());

        String cols = String.join(", ",
                columnNames.stream()
                .skip(1)
                .collect(Collectors.joining(",")),
                columnNames.get(0));

        StringJoiner j = new StringJoiner(",");
        for (String column : columnNames) { j.add("?"); }
        String insert = "INSERT INTO " + tableName + "(" + cols + ")" +
            "VALUES (" + j.toString() + ")";

        processUpdate(insert, toInsert);
    }

    private void processUpdate(String dml,
                               List<Object[]> rows) throws SQLException {
        if (rows.isEmpty()) { return; }

        try(PreparedStatement stmt = conn.prepareStatement(dml)) {
            for (Object[] row : rows) {
                int cols = getColumnCount();
                stmt.setObject(cols, row[1]);
                for (int i = 1; i < cols; i++) {
                    stmt.setObject(i, row[i+1]);
                }
            }
            stmt.executeUpdate();
        }
    }

    private void handleUpdates() throws SQLException {
        List<Object[]> toUpdate = data.stream()
            .filter(o -> o[0] != null && o[0].equals("UPDATE"))
            .collect(Collectors.toList());

        StringJoiner j = new StringJoiner(", ");
        String cols = columnNames.stream()
            .skip(1)
            .map(col -> col + "= ?")
            .collect(Collectors.joining(", "));

        String update = "UPDATE " + tableName + " SET " + cols +
            " WHERE " +  columnNames.get(0) + "= ?";

        processUpdate(update, toUpdate);

    }
}
```





```
import javax.swing.*;
import java.sql.*;

public class Test {


    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "test", "test");
        JdbcTableModel model = new JdbcTableModel(conn, "SELECT id, Nachname, Vorname FROM adressen");
        JButton save = new JButton("Speichern");
        save.addActionListener(e -> {
            try { model.save(); } catch (SQLException ex) { ex.printStackTrace(); }
        });

        JButton refresh = new JButton("Refresh");
        refresh.addActionListener(e -> model.requery());

        JButton insert = new JButton("Neu");
        insert.addActionListener(e -> model.insertRow());

        JPanel panel = new JPanel();
        panel.add(save);
        panel.add(insert);
        panel.add(refresh);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(new JScrollPane(new JTable(model)));
        frame.add(panel, java.awt.BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }

}
```


----------



## NichtExpert (17. Mrz 2020)

mihe7 hat gesagt.:


> Hier mal kurz was zusammengeschustert, nicht schön aber selten:


Hallo, vielen Dank für das Beispiel.
Habe mal den Code bei mir eingesetzt und die Zugriffsdaten geändert.
Leider bekomme ich eine Fehlermeldung:

java.sql.SQLException: Parameter index out of range (6 > number of parameters, which is 0).

Deinen Code habe ich mir angeguckt, konnte kein Index "6 >" finden.

Meine sql-Datenbank hat aus testgründen nur 5 einträge (Zeilen). Daher dachte ich, Hey... es könnte daran liegen und habe mal ein paar zeilen hinzugefügt.
Folge --> Dasselbe.       Parameter index out of range (6 > number of parameters, which is 0)

Daher müsste es irgendwo am Code liegen.

Kannst du mir da nochmal helfen bzw weiß irgendeiner etwas?


----------



## mihe7 (17. Mrz 2020)

Hast Du den SELECT angepasst?


----------



## NichtExpert (17. Mrz 2020)

mihe7 hat gesagt.:


> Hast Du den SELECT angepasst?




```
JdbcTableModel model = new JdbcTableModel(conn, "SELECT * FROM personalie");
```


----------



## mihe7 (17. Mrz 2020)

Das passt irgendwie nicht recht zusammen, daher ein paar Nachfragen:

1. Du hast den Code genommen und nur die Connection URL und den SELECT angepasst?
2. Du bekommst die Tabelle angezeigt?
3. Beim Klick auf Speichern bekommst Du die Exception?

Du kannst Dir in processUpdate einfach mal dml ausgeben lassen.


----------



## NichtExpert (17. Mrz 2020)

mihe7 hat gesagt.:


> Das passt irgendwie nicht recht zusammen, daher ein paar Nachfragen:
> 
> 1. Du hast den Code genommen und nur die Connection URL und den SELECT angepasst?
> 2. Du bekommst die Tabelle angezeigt?
> 3. Beim Klick auf Speichern bekommst Du die Exception?


1. Ja Genau
2. Die tabelle wird angezeigt
3. Richtig. Wenn ich auf speichern drücke, wird sie ausgelöst


----------



## NichtExpert (17. Mrz 2020)

Ok habe noch etwas herausgefunden, was ich persönlich sehr komisch finde:
Wenn ich das ganze mit der SQL-Tabelle 'personalie' mache, kommt es zum Fehler.
Wenn ich das ganze mit der SQL-Tabelle 'customer' mache, funktioniert es einwandfrei.
Die Beiden Tabellen befinden sich in derselben Datenbank 

Grund dafür?


----------



## NichtExpert (17. Mrz 2020)

bei einer 3 Tabelle in einer anderen Datenbank kommt folgende Fehlermeldung:

```
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(min.), nr.)VALUES (null,null,null,null)' at line 1
```
Habe versucht ihn richtig hinzubekommen aber ohne Erfolg


----------



## NichtExpert (17. Mrz 2020)

Jetzt funktioniert keine mehr. Nur die eine Fehlermeldung kommt jetzt dauerhaft 
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(min.), nr.)VALUES (null,null,null,null)' at line 1


----------



## mihe7 (17. Mrz 2020)

Du kannst in dem Beispiel keine Funktionen abfragen (/e: im SELECT verwenden). Das wären Spalten, die nur in der Abfrage, nicht aber in der Tabelle existieren. Dazu müsstest Du den INSERT und UPDATE-Teil umschreiben.

Nachtrag: ebenfalls nicht unproblematisch ist das Verwenden von Views für INSERT und UPDATE.


----------



## NichtExpert (18. Mrz 2020)

mihe7 hat gesagt.:


> Dazu müsstest Du den INSERT und UPDATE-Teil umschreiben.


Alsoin der Klasse : jdbcTableModel ?


----------



## mihe7 (18. Mrz 2020)

NichtExpert hat gesagt.:


> Alsoin der Klasse : jdbcTableModel ?


Das Modell war einfach als Test gedacht: eine simple Tabelle aus der DB anzeigen, Sätze einfügen und aktualisieren. Dabei muss die ID-Spalte die erste in der durch den SELECT definierten Tabelle sein. Es verwendet einfach die Spaltennamen als Tabellen-Überschrift. 

Es ging nur darum, Deinen Fehler weg zu bekommen. Dass sich nebenher noch anderes herausstellte, war ja eher Zufall.

Du kannst die Klasse als Basis nutzen oder auch nicht - das spielt keine Rolle. Es geht ums Prinzip. Du kannst den DB-Teil in eine eigene Klasse auslagern (s. Repository-Pattern) und das TableModel daran anpassen etc. etc.


----------



## NichtExpert (18. Mrz 2020)

ich experimentiere mal, so soll's schließlich auch gemacht werden. [Forum: Tipps einholen, anhand BSP, erklährungen, anregungen, etc --> selber zum Ergebnis kommen]


----------

