webentwicklung-frage-antwort-db.com.de

Wie fülle ich Daten in einer JTable mit Datenbank?

Ich möchte eine JTable anzeigen, die die Daten aus einer DataBase-Tabelle so anzeigt, wie sie ist.

Bis jetzt habe ich JTable verwendet, das Daten von Object [] [] anzeigt.

Ich weiß, eine Möglichkeit, die Daten anzuzeigen, besteht darin, zuerst die Datenbanktabelle in Object [] [] zu konvertieren. Gibt es eine andere, die einfach und dennoch leistungsfähiger und flexibler ist. 

19
Yatendra Goel

Ich würde den folgenden Ansatz empfehlen:

  • Erstellen Sie eine Row-Klasse, um eine Zeile darzustellen, die von Ihrer ResultSet gelesen wird. Dies könnte ein einfacher Wrapper für einen Object[] sein.
  • Erstellen Sie eine List<Row>-Sammlung und eine Unterklasse AbstractTableModel, die von dieser Sammlung unterstützt werden soll.
  • Verwenden Sie eine SwingWorker, um Ihren List<Row> zu füllen, indem Sie aus der zugrunde liegenden ResultSet in einem background-Thread lesen (d. H. Innerhalb der doInBackground()-Methode). Rufen Sie die SwingWorker-Methode von publish auf, um Rows wieder im Event Dispatch-Thread zu veröffentlichen (z. B. alle 100 Zeilen).
  • Wenn die SwingWorker-Methode der process mit dem letzten gelesenen Teil der Zeilen aufgerufen wird, fügen Sie sie zu Ihrem List<Row> hinzu und lösen die entsprechenden TableEvents aus, um die Anzeige zu aktualisieren.
  • Verwenden Sie die Variable ResultSetMetaData, um die Variable Class jeder Spalte in der Definition von TableModel zu bestimmen. Dies führt dazu, dass sie korrekt gerendert werden (was bei einer einfachen Verwendung eines 2D Object[][]-Arrays nicht der Fall ist).

Der Vorteil dieses Ansatzes besteht darin, dass die Benutzeroberfläche bei der Verarbeitung großer ResultSets nicht blockiert und die Anzeige bei der Verarbeitung der Ergebnisse inkrementell aktualisiert wird.

EDIT

Beispielcode hinzugefügt:

/**
 * Simple wrapper around Object[] representing a row from the ResultSet.
 */
private class Row {
  private final Object[] values;

  public Row(Object[] values) {
    this.values = values;
  }

  public int getSize() {
    return values.length;
  }

  public Object getValue(int i) {
    return values[i];
  }
}

// TableModel implementation that will be populated by SwingWorker.
public class ResultSetTableModel extends AbstractTableModel {
  private final ResultSetMetaData rsmd;
  private final List<Row> rows;

  public ResultSetTableModel(ResultSetMetaData rsmd) {
    this.rsmd = rsmd;
    this.rows = new ArrayList<Row>();
  }

  public int getRowCount() {
    return rows.size();
  }

  public int getColumnCount() {
    return rsmd.getColumnCount();
  }

  public Object getValue(int row, int column) {
    return rows.get(row).getValue(column);
  }

  public String getColumnName(int col) {
    return rsmd.getColumnName(col - 1); // ResultSetMetaData columns indexed from 1, not 0.
  }

  public Class<?> getColumnClass(int col) {
    // TODO: Convert SQL type (int) returned by ResultSetMetaData.getType(col) to Java Class.
  }
}

// SwingWorker implementation
new SwingWorker<Void, Row>() {
  public Void doInBackground() {
    // TODO: Process ResultSet and create Rows.  Call publish() for every N rows created.
  }

  protected void process(Row... chunks) {
    // TODO: Add to ResultSetTableModel List and fire TableEvent.
  }
}.execute();
24
Adamski

Eine weitere leistungsstarke und flexible Möglichkeit, Datenbankdaten in einer JTable anzuzeigen, besteht darin, die Ergebnisdaten Ihrer Abfrage in einen CachedRowSet zu laden und sie dann mit JTable mit TableModel - Adapter zu verbinden.

  1. Abfrage ---> Datenbankdaten ---> RowSet
  2. RowSet <-> TableModel-Adapter <-> JTable

Dieses book von George Reese gibt den Quellcode für seine Klasse RowSetModel, um ein RowSet als TableModel anzupassen. Arbeitete für mich out-of-the-box. Meine einzige Änderung war ein besserer Name für die Klasse: RowSetTableModel.

Ein RowSet ist eine in Java 1.4 hinzugefügte Subschnittstelle von ResultSet. Also ein RowSet is ein ResultSet.

Eine CachedRowSet-Implementierung erledigt die Arbeit für Sie, anstatt eine Row-Klasse, eine Liste von Row-Objekten und ResultSetMetaData zu erstellen, wie in den anderen Antworten auf dieser Seite beschrieben.

Sun/Oracle bietet eine Referenzimplementierung von CachedRowSet. Andere Hersteller oder JDBC-Treiber können ebenfalls Implementierungen bereitstellen.

RowSet-Tutorial

7
Basil Bourque

Je nachdem, was Sie bereits getan haben und was Sie tun möchten, habe ich Netbeans mit Beans Binding-Unterstützung für eine datenbankgesteuerte Anwendung sehr erfolgreich verwendet. Sie binden Ihre JTable an eine Datenbank und die JPA-Abfragen werden automatisch erstellt.

4
Jon

Bester Weg, um jTable mit ResultSet zu füllen

Voraussetzungen

1) Ergebnismenge "rs" wird mit Daten gefüllt, die Sie benötigen . 2) Die JTabelle "jTable1" wird vor dem Handblatt erstellt

Implementierung

        Java.sql.ResultSet rs = datacn.executeSelectQuery(query);
        //Filling JTable with Result set

        // Removing Previous Data
        while (jTable1.getRowCount() > 0) {
            ((DefaultTableModel) jTable1.getModel()).removeRow(0);
        }

        //Creating Object []rowData for jTable's Table Model        
        int columns = rs.getMetaData().getColumnCount();
        while (rs.next())
        {  
            Object[] row = new Object[columns];
            for (int i = 1; i <= columns; i++)
            {  
                row[i - 1] = rs.getObject(i); // 1
            }
            ((DefaultTableModel) jTable1.getModel()).insertRow(rs.getRow() - 1,row);
        }
4
Yogesh

Sie müssen ein benutzerdefiniertes TableModel erstellen. Dort können Sie angeben, woher und wie die Daten stammen. 

Sie müssen erst wirklich verstehen, wie JTable + TableModel funktioniert und dann einer der zuvor veröffentlichten Antworten folgen. 

3
OscarRyz

Ich weiß, dass die Frage alt ist, aber für jeden, der der Lösung von Adamski folgt, ist Vorsicht geboten, wenn die ResultSet und ResultSetMetadata zwischen gui und SwingWorker geteilt werden. Ich habe eine inkonsistente Ausnahmebedingung für den internen Status erhalten, als ich diesen Ansatz mit SQLite verwendete. Die Lösung besteht darin, alle Metadaten in private Felder zu laden, bevor SwingWorker ausgeführt wird, und die Getter-Funktionen (getColumnName usw.) verwenden, um stattdessen die Felder zurückzugeben.

1
j_kar

Ich gebe eine kleine Methode zum Anzeigen von Datenbanktabellendaten in JTable. Sie müssen nur das Resultset der Datenbanktabelle als Parameter ..__ übergeben.


    // rs is the ResultSet of the Database table
    public void displayData(ResultSet rs)
    {
        //jt Represents JTable
        //jf represents JFrame
        int i;
        int count;
        String a[];
        String header[] = {"1","2","3","4","5"};   //Table Header Values, change, as your wish
        count = header.length;

//First set the Table header for(i = 0; i < count; i++) { model.addColumn(header[i]); } jt.setModel(model); //Represents table Model jf.add(jt.getTableHeader(),BorderLayout.NORTH); a = new String[count]; // Adding Database table Data in the JTable try { while (rs.next()) { for(i = 0; i < count; i++) { a[i] = rs.getString(i+1); } model.addRow(a); //Adding the row in table model jt.setModel(model); // set the model in jtable } } catch (Exception e) { JOptionPane.showMessageDialog(null, "Exception : "+e, "Error", JOptionPane.ERROR_MESSAGE); } }
0
Ram