You are not logged in.

  • Login

1

Wednesday, June 3rd 2009, 4:40pm

Resultset in JTable

Hallo allerseits,

wirklich starkes Forum habt ihr hier!
bisher reichte mir das mitlesen, aber nun "muss" ich nun auch mal aktiv nachhacken..

Mein Problem liegt darin, dass ich nicht so recht mit abstract table models klar komme.
Ich habe eine Tabellenklasse und eine AbstractModelClass.

Java Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package gfx.client;
 
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
 
import javax.swing.table.AbstractTableModel;
 
public class mymodel extends AbstractTableModel {
 
//Initiierung div. datenbankspezifischer Varbiablen
  static final String LOG_FILE = "jdbc.log";
  static final String USER     = "root";
  static final String PW       = "root";
  static final String URL      = "jdbc:mysql://localhost/db";
 String sql = "select * from tb1";
  MysqlDataSource mds = new MysqlDataSource();
  Connection con = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
 
 public int getColumnCount() {...}
  public int getRowCount() {...}
  public Object getValueAt( int row, int col) {...}
   public String getColumnName(int c){...}
  public boolean isCellEditable( int row, int col) {...}
}


Leider weiß ich absolut nicht, wie ich die o.g. Methoden modifizieren soll, damit mein Resultset in der Tabelle dargestellt wird.
Bei meiner Googlearie bin ich auf folgendes Bsp. gestoßen, was aber nicht mit einem tablemodell arbeitet:

Java Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package gfx.client;
 
import java.awt.*;
import java.awt.event.MouseAdapter;
 
import java.awt.event.MouseEvent;
 
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
 
public class TableDB extends JInternalFrame
{
  public static String sql_preview ;
 
	public TableDB( String sql_preview){
    Vector columnNames = new Vector();
        Vector data = new Vector();
 
        try
        {
            //  Connect to the Database
 
            String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
            String url = "jdbc:mysql://localhost/hotel";
            String userid = "root";
            String password = "root";
 
            Class.forName( driver );
            Connection connection = DriverManager.getConnection( url, userid, password );
 
            //  Read data from a table
 
            Statement stmt = connection.createStatement();
          ResultSet rs = stmt.executeQuery( sql_preview );
            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();
 
            //  Get column names
 
            for (int i = 1; i <= columns; i++)
            {
                columnNames.addElement( md.getColumnName(i) );
            }
 
            //  Get row data
 
            while (rs.next())
            {
                Vector row = new Vector(columns);
 
                for (int i = 1; i <= columns; i++)
                {
                    row.addElement( rs.getObject(i) );
                }
 
                data.addElement( row );
            }
 
            rs.close();
            stmt.close();
        }
        catch(Exception e)
        {
            System.out.println( e );
        }
 
        //  Create table with database data
 
        JTable table = new JTable(data, columnNames)
        {
			public Class getColumnClass(int column)
			{
				return getValueAt(0, column).getClass();
			}
        };
 
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
 
        JPanel buttonPanel = new JPanel();
        getContentPane().add( buttonPanel, BorderLayout.SOUTH );
    try {
      jbInit();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 
    public static void main(String[] args)
    {
        TableDB frame = new TableDB( sql_preview );
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
 
        frame.setVisible(true);
 
 
    }
 
  private void jbInit() throws Exception {
  }
 
}


Leider weiß ich nicht so recht, wie ich weiter vorgehen soll. Das "How to use JTable" von Sun hat mir auch nicht weiter geholfen, bzw. habe ich dazu weder ein gutes Tut, noch ein nettes Beispiel gefunden.

Hoffe, dass mir hier geholfen werden kann.

Juanito

2

Wednesday, June 3rd 2009, 8:23pm

Du willst das Ergebnis in einer jTable darstellen. Deswegen gehe ich mal davon aus, das das Ergebnis deines SQL-Statements in den Speicher passt.

Aus diesem Grund würde ich die komplette Auswertung des ResultSet im Konstruktor machen. Dann kannst du deine Datenbankverbindung gleich schließen, nachdem du dein TableModel initialisiert hast.

Java Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class MyTableModel extends AbstractTableModel
	{
		private static final long serialVersionUID = 1L;
 
		private LinkedHashMap<Integer, List<Object>> data = new LinkedHashMap<Integer, List<Object>>();
 
		public MyTableModel(ResultSet resultSet) throws SQLException
		{
			int maxColumns = resultSet.getMetaData().getColumnCount();
			for (int i = 0; i < maxColumns; i++)
			{
				data.put(i, new LinkedList<Object>());
			}
 
			int row = 0;
			while (resultSet.next())
			{
				for (Integer column : data.keySet())
				{
					data.get(column).add(row, resultSet.getObject(column));
				}
				row++;
			}
		}
 
 
		@Override
		public int getColumnCount()
		{
			return data.size();
		}
 
		@Override
		public int getRowCount()
		{
			if (data.isEmpty())
			{
				return 0;
			}
			else
			{
				return data.values().iterator().next().size();
			}
		}
 
		@Override
		public Object getValueAt(int rowIndex, int columnIndex)
		{
			return data.get(columnIndex).get(rowIndex);
		}
 
	}


Achtung ungetesteter Code!

3

Thursday, June 4th 2009, 3:30pm

okay, ich muss nur kurz dahinter kommen:

ich habe ein Panel, per Klick soll eine JFrame mit DB erzeugt werden.
Ich rufe auf dem Panel per Buttonklick mein Objekt auf. Als Parameter wird der SQL String übergeben und dem Konstruktor wird gesagt, dass er es mit mytablemodel erstellen soll, richtig?

im mytablemodel wird dann eine DB Verbindung erstellt und das ResultSet erzeugt. Den Rest sollte deine Klasse übernehmen, oder?

Merci0r

4

Thursday, June 4th 2009, 7:39pm

Quoted

per Klick soll eine JFrame mit DB erzeugt werden.

Bitte was? Du erzeugst doch keine Datenbank per klick. Du baust eher eine Verbindung zur Datenbank auf. Wann du das machen solltest kann ich dir nicht sagen, da ich deinen Programmaufbau nicht kenne.

Java Quellcode

1
Ich rufe auf dem Panel per Buttonklick mein Objekt auf. Als Parameter wird der SQL String übergeben und dem Konstruktor wird gesagt, dass er es mit mytablemodel erstellen soll, richtig?

Was ist den dein Objekt? Die Tabelle? Warum noch ein Buttonklick? Wohin wird der SQL-String als Parameter übergeben? Konstruktor vom JTable?

Also in meinem Beispiel übergibt man das ResultSet dem MyTableModel (du kannst das auch gern umbenennen). Demnach muss musst du die Datenbankverbingung und die Abfrage vorher ausführen. Als Ergebnis bekommst du ein ResultSet. Das kannst du dem Konstruktor von MyTableModel übergeben und bekommst so ein MyTableModel-Objekt. Dieses MyTableModel-Objekt kannst du dem Konstruktor von JTable übergeben. Dieses JTable-Objekt fügst du nun einer anderen Swing-Komponente (z.B. einem JPanel) hinzu.

5

Thursday, June 4th 2009, 7:57pm

Hallo,

sorry. das waren wohl ein paar wenig Infos..
bis dato verwende ich aus Funktionsgründen die o.g. Klasse MIT Frame.
Diese rufe ich per onclick-Actionevent auf und gebe dem Aufruf das sql Statement mit.
Sprich:
TableDB tab = new TableDB (sql);

im Konstruktor werden dann die Daten in die DB geschrieben usw..
ich weiß zB gerade nicht, wie ich den Konstruktor aufrufe, ihm sage, dass er mein TableModel benutzen und den Parameter übernehmen soll.

Ich werde dein Code gleich mal austesten.

Danke

6

Thursday, June 4th 2009, 8:02pm

Erbt deine Klasse TableDB von irgend etwas?

7

Thursday, June 4th 2009, 8:46pm

nein. wieso?

sie bekommt einfach das SQL Statement als String übergeben, damit die Tabelle variable auf versch. Statements reagieren kann.
Die Tabelle soll woanders auch nochmal aufgerufen werden.

Ich bin gerade wieder "from a scratch" am basteln.

vielleicht kann ich es so ein bisschen mehr verdeutlichen (Strukturmäßig)
Frame -> Panel auf Frame -> Button, Textfield auf Panel -> in das Textfield soll ein SQL Statement geschrieben und per Buttonklick die Table erzeugt werden -> Klick erzeugt Konstruktor und übergibt ihm Inhalt vom Textfield -> Konstruktor beinhaltet mein TableModel, welches den Inhalt erzeugt.

Im Prinzip kann ich doch dem TableModel beim Aufruf auch wieder den String mitgeben und schon erzeugt er den Spaß auch so, oder?
Jetzt muss ich nurnoch Daten aus der DB kriegen ;)


ByeBye

This post has been edited 2 times, last edit by "don juan" (Jun 4th 2009, 8:55pm)


8

Thursday, June 4th 2009, 9:22pm

Deine Überschrift lautet doch "Resultset in JTable". Wo ist denn deine JTable? Wann wird die JTable zum Panel hinzugefügt, damit man sie sehen kann. Das AbstractTableModel ist für die JTable gemacht.

9

Thursday, June 4th 2009, 9:30pm

Ich hoffe, dass ich dich richtig verstehe:
Also ich habe ein Panel auf dem ganz normal via:

Source code

1
private JTable tab = nee JTable(new mymodel());


die Tabelle erzeugt wird. Lassen wir es erstmal komplett sichtbar, damit ich nicht gleich zu viel auf einmal will ;)

Mein Problem ist es gerade, deinen Code mit meinen DB Daten zu füttern. Ansonsten siehts ganz gut aus (s.o).

bb

10

Thursday, June 4th 2009, 9:44pm

Java Quellcode

1
private JTable tab = new JTable();


Java Quellcode

1
2
3
4
5
6
Statement stmt = connection.createStatement();
String query = "SELECT * FROM Tabellenname"; // Das musst du dir natürlich aus dem Eingabefeld holen.
ResultSet rs = stmt.executeQuery( query );
MyTableModel tableModel = new MyTableModel(rs);
stmt.close();
tab.setModel(tableModel);


Eventuell muss die GUI noch mal neu gezeichnet werden (wenn es nicht schon automatisch geht) dafür musst du dann am JFrame in dem die JTable liegt diese Befehle ausführen:

Java Quellcode

1
2
validate();
repaint();

11

Saturday, June 6th 2009, 1:33pm

mhhhhhhhh..
von der Tabelle an sich scheint es klappen.
Aber die Darstellung / Aufbau ist grauenhaft.
ich muss das Fenster mehrfach ein/ausblenden und mit der Maus über das Objekt gehen, damit ich was lesen kann.
außerdem erhalte ich eine null pointer exception, die ich nirgends zuteilen kann.


Naja, Vielen Dank auf jeden Fall erstmal. Um den Rest muss ich mich wohl kümmern;)

Dank!

Social bookmarks