Resultset in JTable

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • 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.

    Quellcode

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


    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:

    Quellcode

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


    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
  • 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.

    Quellcode

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


    Achtung ungetesteter Code!
  • 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
  • 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.

    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.
  • 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
  • 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

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von don juan ()

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

    Quellcode

    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
  • Quellcode

    1. private JTable tab = new JTable();


    Quellcode

    1. Statement stmt = connection.createStatement();
    2. String query = "SELECT * FROM Tabellenname"; // Das musst du dir natürlich aus dem Eingabefeld holen.
    3. ResultSet rs = stmt.executeQuery( query );
    4. MyTableModel tableModel = new MyTableModel(rs);
    5. stmt.close();
    6. 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:

    Quellcode

    1. validate();
    2. repaint();
  • 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!