# von Datenbank in JTable füllen



## dogano (9. Mai 2012)

Hallo,

Ich habe ein kleines Problem. Ich möchte Attribute aus der Datenbank in ein JTable füllen. Mein JTable habe ich wie folgt erstellt:


```
PAusgabe = new JPanel();
    	PAusgabe.setBounds(20,335,620,265);
    	PAusgabe.setOpaque(true);
    	PAusgabe.setBackground(Color.white);
    	Hauptfenster.add(PAusgabe);
    	
    	final String[][] columnNames = {
    			
        };
        final String[] data = {
        		"Gesellschaftsform","Webseite","TelNr","Fax","Stadt","Strasse","Hausnummer","PLZ"
        };
    	
    	final JTable table = new JTable(columnNames,data);
    	table.setPreferredScrollableViewportSize(new Dimension (600,240));
    	table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    	JScrollPane pane = new JScrollPane(table);
    	PAusgabe.add(pane, BorderLayout.CENTER);
    	pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
```

Wenn ich jetzt manuell in "columnNames" Daten eintrage, dann werden sie auf der GUI(im Table) angezeigt. Meine Frage ist jetzt, wie ich die Datenbankabfrage machen muss um "columnNames" zu füllen?! 

Ich weiß dass ich etwas in der Form haben muss:


```
//Verbindung aufbauen
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb?user=&password=");
		   	Statement stm = conn.createStatement();	
		   	String sql = "SELECT * FROM fiku";				           
		   	ResultSet rs = stm.executeQuery(sql);
		   	
		   	while(rs.next()){
		 
		   	}
		   	
             stm.close();
        	conn.close();
```

Hier muss ja in der while-Anweisung etwas passieren. Kann mir jemand helfen wie genau ich das gestalten muss?

Liebe Grüße,

dogano


----------



## Camino (9. Mai 2012)

http://www.java-forum.org/bilder-gui-damit-zusammenhaengt/4841-jtable-ubersicht-teil-1-teil-8-a.html
Hier wird auch erklärt, wie JTables grundsätzlich aufgebaut sind und wie die Daten in die Tabelle kommen. An deiner Stelle würde ich mit einem TableModel arbeiten, welches die Daten aus der DB einliest und dann über das TableModel (abgeleitet von AbstractTableModel) in die JTable bringt.

In der while-Schleife mit dem rs.next() gehst du durch alle deine Datensätze im ResultSet durch. Diese könntest du z.B. in einer ArrayList sammeln, welche dann über das TableModel in die JTable gebracht werden.

EDIT: Ich vermute mal, es handelt sich um Kontaktdaten oder Adressen, welche du aus der Datenbank auslesen möchtest. Du könntest also auch eine Klasse Adresse erstelle, welche genau diese Felder der DB-Tabelle hat. Dann erstellst du eine ArrayList<Adresse>, welche Objekte von Adresse aufnehmen kann. Mit rs.next() gehst du durch dein ResultSet durch und erstellst zu jedem Datensatz ein Objekt der Klasse Adresse gefüllt mit den Daten. Dieses Objekt fügst du der ArrayList hinzu.


----------



## dogano (9. Mai 2012)

Hey,

das mit der Klasse bietet sich eher weniger an, da ich Aufgabenbedingt viel Programmcode haben muss. Daher ohne Klassen...
Mein Programmcode sieht jetzt etwa so aus:


```
//Hauptfenster
	final JFrame Hauptfenster;
	Hauptfenster = new JFrame();
	Hauptfenster.setBounds(0,0,250,250);
	Hauptfenster.setDefaultCloseOperation(Hauptfenster.EXIT_ON_CLOSE);
	Hauptfenster.setName("Über Uns");
	Hauptfenster.setTitle("Über Uns");
	Hauptfenster.setSize(650,650);
	Hauptfenster.setResizable(false);
	Hauptfenster.setLayout(null);
	Hauptfenster.setLocationRelativeTo(null);

    
	final String[][] data = new String[20][20];
	String[] columnnames = new String[20];
		    
.....

	Suche.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e){
	        try {
	        	//Verbindung aufbauen
	            Class.forName("com.mysql.jdbc.Driver").newInstance();
	            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb?user=&password=");
			   	Statement stm = conn.createStatement();	
			   	String sql = "SELECT * FROM fiku";				           
			   	ResultSet rs = stm.executeQuery(sql);
			    rs.last();
			    int laenge = rs.getRow();
				rs.beforeFirst();
				int k = 0;

				while(rs.next()){
					
					for(int i=1;i<=laenge;i++){
						String s =  rs.getString(i+1);
						data[k][i] = s;
					}
					k++;
				}
	
			            rs.close();
			            stm.close();		            
		           		
		            conn.close();

	        } 
		          catch (Exception ex) {
	            // Fehler behandeln
	        	System.out.println(ex.toString());
	        } 
			
		}
	});

	PAusgabe = new JPanel();
	PAusgabe.setBounds(20,335,620,265);			  
        final JTable table = new JTable(data, columnnames );
        table.setPreferredScrollableViewportSize(new Dimension (600,240));
        table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
	JScrollPane pane = new JScrollPane(table);
        PAusgabe.add(pane, BorderLayout.CENTER);
        pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        Hauptfenster.add(PAusgabe);
```

Ich bekomme aber das Table jetzt nicht angezeigt. Wenn ich das Table weiter oben deklariere und setze, sehe ich es zwar, aber da ja zu dem Zeitpunkt in "data" noch nix steht, wird die Tabelle auch für ewig leer bleiben. Kann mir jemand helfen?


----------



## c_sidi90 (9. Mai 2012)

> as mit der Klasse bietet sich eher weniger an, da ich Aufgabenbedingt viel Programmcode haben muss.


 woot? Du musst viel Code haben anstatt elegant übersichtlich und schlank ? Mal davon abgesehen davon, dass wenn du eine Adressen-Klasse hast der Code nicht weniger wird, sondern übersichtlicher.

Mach dir lieber ein TableModel von mir aus vom Typ DefaultTableModel, dies initialisierst du am Ende deiner Datenbankmethode und übergibst diesem model das data und column Array. Im Anschluss übergibst du dann dieses model deiner tabelle via
	
	
	
	





```
table.setModel(deinModel)
```

Wo ist die Komponente "Suchen" in deinem Code überhaupt ? Reagiert der ActionListener denn? Probier mal ein System.out.println zum loggen.


----------



## dogano (9. Mai 2012)

Hey,

nein das mit dem viel Programmcode war eher so gemeint, dass ich am Ende 10 Seiten Programmcode ausdrucken und abgeben muss. Ich habe jetzt schon fast alle anderen Teile der DB-Abfragen einfach in den ActionListener gepackt. Jetzt würde es einfach nur noch doof aussehen wenn ich den Rest in ne Klasse packe. Ich werde eh schön aufräumen wenn ich fertig bin.

Kannst du mir vielleicht ein Beispiel anhand meines Programmcodes geben? Wie mach ich das mit dem Model? Du bist jetzt der zweite der das sagt.. 

Würde mich echt freuen 

Die Komponennte Suchen ist ein Button. Die reagiert, da bin ich mir sicher 

Liebe Grüße,

dogano


----------



## Camino (9. Mai 2012)

Schau mal hier:
http://www.java-forum.org/bilder-gui-damit-zusammenhaengt/7035-jtable-teil-2-kommen-daten-tabelle.html

Da ist unter Punkt 3 das mit dem DefaultTableModel genauer erklärt. Das kannst du dann auch fast genauso in deinen Programmcode reinschreiben.

OK, genauso reinschreiben ist vielleicht übertrieben. Interessant ist für dich in dem Beispiel die Methode bzw. der ActionListener, der neue Zeilen hinzufügt (buttonAddRow). Mit model.addRow fügst du dem Model neue Datensätze hinzu.


----------



## dogano (9. Mai 2012)

hey,

danke für eure antworten!! 
Würde es bei mir dann etwa so aussehen?


```
//Hauptfenster
    final JFrame Hauptfenster;
    Hauptfenster = new JFrame();
    Hauptfenster.setBounds(0,0,250,250);
    Hauptfenster.setDefaultCloseOperation(Hauptfenster.EXIT_ON_CLOSE);
    Hauptfenster.setName("Über Uns");
    Hauptfenster.setTitle("Über Uns");
    Hauptfenster.setSize(650,650);
    Hauptfenster.setResizable(false);
    Hauptfenster.setLayout(null);
    Hauptfenster.setLocationRelativeTo(null);

    PAusgabe = new JPanel();
    PAusgabe.setBounds(20,335,620,265);           
    final JTable table = new JTable();
    table.setPreferredScrollableViewportSize(new Dimension (600,240));
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    JScrollPane pane = new JScrollPane(table);
    PAusgabe.add(pane, BorderLayout.CENTER);
    pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
    Hauptfenster.add(PAusgabe);
 
    
    final String[][] data = new String[20][20];
    String[] columnnames = new String[20];

            
.....
 
    Suche.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try {
                //Verbindung aufbauen
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb?user=&password=");
                Statement stm = conn.createStatement(); 
                String sql = "SELECT * FROM fiku";                         
                ResultSet rs = stm.executeQuery(sql);
                rs.last();
                int laenge = rs.getRow();
                rs.beforeFirst();
                int k = 0;
 
                while(rs.next()){
                    
                    for(int i=1;i<=laenge;i++){
                        String s =  rs.getString(i+1);
                        data[k][i] = s;
                    }
                    k++;
                }
    
                        rs.close();
                        stm.close();                    
                        
                    conn.close();
 
            } 
                  catch (Exception ex) {
                // Fehler behandeln
                System.out.println(ex.toString());
            } 
            
        }
    });
 

    final DefaultTableModel model = new DefaultTableModel(columnnames, data);
    table.setModel(model);
```


----------



## c_sidi90 (9. Mai 2012)

Ja kann man so machen, funktioniert es so ? Mir fällt auch gerade auf das du deinem Tablemodel die Parameter falsch angibst. Ich meine jetzt frei aus dem Kopf das das data[][] zuerst übergeben werden muss und folglich die columnnames


----------



## dogano (9. Mai 2012)

Ich habe es jetzt so gemacht :


```
//Hauptfenster
    final JFrame Hauptfenster;
    Hauptfenster = new JFrame();
    Hauptfenster.setBounds(0,0,250,250);
    Hauptfenster.setDefaultCloseOperation(Hauptfenster.EXIT_ON_CLOSE);
    Hauptfenster.setName("Über Uns");
    Hauptfenster.setTitle("Über Uns");
    Hauptfenster.setSize(650,650);
    Hauptfenster.setResizable(false);
    Hauptfenster.setLayout(null);
    Hauptfenster.setLocationRelativeTo(null);
 
    PAusgabe = new JPanel();
    PAusgabe.setBounds(20,335,620,265);           
    final JTable table = new JTable();
    table.setPreferredScrollableViewportSize(new Dimension (600,240));
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    JScrollPane pane = new JScrollPane(table);
    PAusgabe.add(pane, BorderLayout.CENTER);
    pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
    Hauptfenster.add(PAusgabe);

  final DefaultTableModel model = new DefaultTableModel(columnnames, 0);
    table.setModel(model);
 
    
    final String[][] data = new String[20][20];
    String[] columnnames = {"ID", "Name","Gesellschaftsform","Webseite","Telefon","Fax"};
 
            
.....
 
    Suche.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try {
                //Verbindung aufbauen
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb?user=&password=");
                Statement stm = conn.createStatement(); 
                String sql = "SELECT * FROM fiku";                         
                ResultSet rs = stm.executeQuery(sql);
                rs.last();
                int laenge = rs.getRow();
                rs.beforeFirst();
                int k = 0;
 
                while(rs.next()){
                    
                    for(int i=1;i<=laenge;i++){
                        String s =  rs.getString(i+1);
                        data[k][i] = s;
                        model.addRow(data):
                    }
                    k++;
                }
    
                        rs.close();
                        stm.close();                    
                        
                    conn.close();
 
            } 
                  catch (Exception ex) {
                // Fehler behandeln
                System.out.println(ex.toString());
            } 
            
        }
    });
```

Funktioniert fast auch. Nur das, was ich dann in den "rows" ausgegeben bekomme(in jeder Zelle) sieht so aus: "[LJava.lang.String;@348dcd5d]"
Was könnte das sein?


----------



## Camino (9. Mai 2012)

Da ist einmal ein Schreibfehler (Doppelpunkt statt Semikolon)

```
model.addRow(data):
```

Und ausserdem übergibst du später dem Model dein data. Das mit dem addRow(data) brauchst du so nicht. Der Konstruktor für das DefaultTableModel lautet: DefaultTableModel(Object[][] data, Object[] columnNames). Die columNames musst du vor dem TableModel erstellen, weil du es ja für den Konstruktor brauchst.

Am Ende, nachdem du dein data in der Schleife gefüllt hast, schreibst du:

```
final DefaultTableModel model = new DefaultTableModel(data, columnnames);
table.setModel(model);
```


----------



## c_sidi90 (9. Mai 2012)

Ich wollte gerade Fragen wieso du überhaupt was zum laufen bekommst wenn dein Code mindestens 5 Kompilierfehler anzeigen müsste.


----------



## dogano (9. Mai 2012)

da läuft grad gar nix  der programmcode ist auf nem anderen rechner wo ich kein internet grad hab.. daher auch die fehler.. ich teste grad ma und sag euch das ergebnis


----------



## dogano (9. Mai 2012)

Ich habe das jetzt so gelöst:


```
//Hauptfenster
    final JFrame Hauptfenster;
    Hauptfenster = new JFrame();
    Hauptfenster.setBounds(0,0,250,250);
    Hauptfenster.setDefaultCloseOperation(Hauptfenster.EXIT_ON_CLOSE);
    Hauptfenster.setName("Über Uns");
    Hauptfenster.setTitle("Über Uns");
    Hauptfenster.setSize(650,650);
    Hauptfenster.setResizable(false);
    Hauptfenster.setLayout(null);
    Hauptfenster.setLocationRelativeTo(null);
 
    PAusgabe = new JPanel();
    PAusgabe.setBounds(20,335,620,265);           
    final JTable table = new JTable();
    table.setPreferredScrollableViewportSize(new Dimension (600,240));
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    JScrollPane pane = new JScrollPane(table);
    PAusgabe.add(pane, BorderLayout.CENTER);
    pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
    Hauptfenster.add(PAusgabe);
 
 
 
    
    final String[][] data = new String[20][20];
    String[] columnnames = {"ID", "Name","Gesellschaftsform","Webseite","Telefon","Fax"};
 
            
.....
 
    Suche.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try {
                //Verbindung aufbauen
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb?user=&password=");
                Statement stm = conn.createStatement(); 
                String sql = "SELECT * FROM fiku";                         
                ResultSet rs = stm.executeQuery(sql);
                rs.last();
                int laenge = rs.getRow();
                rs.beforeFirst();
                int k = 0;
 
                while(rs.next()){
                    
                    for(int i=1;i<=laenge;i++){
                        String s =  rs.getString(i+1);
                        data[k][i] = s;
                      final DefaultTableModel model = new DefaultTableModel(data, columnnames);
    table.setModel(model);
                    }
                    k++;
                }
    
                        rs.close();
                        stm.close();                    
                        
                    conn.close();
 
            } 
                  catch (Exception ex) {
                // Fehler behandeln
                System.out.println(ex.toString());
            } 
            
        }
    });
```


funktioniert Sahne! Danke für eure Hilfe!!


----------



## Camino (9. Mai 2012)

```
final DefaultTableModel model = new DefaultTableModel(data, columnnames);
table.setModel(model);
```
Das soll nicht bei jedem Schleifendurchlauf ausgeführt werden, sondern nur einmal am Ende, nachdem mit while(rs.next()) dein data gefüllt wurde.


----------



## dogano (9. Mai 2012)

wenn ich das so mache, war es so, dass zwar die columns gefüllt aber nicht sichtbar waren..
so funzt es perfekt


----------



## Camino (9. Mai 2012)

Aber so erzeugst du mit jedem Schleifendurchlauf ein neues TableModel und weist es der Tabelle zu. Das mag vielleicht funktionieren, ist aber etwas übertrieben... Schreib das doch mal nach deinem try-catch-Block hin.


----------



## dogano (9. Mai 2012)

ok, das ging auch


----------

