JTable So aktualisieren Sie das Tabellenmodell nach dem Einfügen, löschen oder aktualisieren Sie die Daten.

88

Das ist meine jTable

private JTable getJTable() {
    String[] colName = { "Name", "Email", "Contact No. 1", "Contact No. 2",
            "Group", "" };
    if (jTable == null) {
        jTable = new JTable() {
            public boolean isCellEditable(int nRow, int nCol) {
                return false;
            }
        };
    }
    DefaultTableModel contactTableModel = (DefaultTableModel) jTable
            .getModel();
    contactTableModel.setColumnIdentifiers(colName);
    jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    return jTable;
}

Ich werde diese Methode aufrufen, um die Daten aus der Datenbank abzurufen und in das Tabellenmodell einzufügen

public void setUpTableData() {
    DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();
    ArrayList<Contact> list = new ArrayList<Contact>();
    if (!con.equals(""))
        list = sql.getContactListsByGroup(con);
    else
        list = sql.getContactLists();
    for (int i = 0; i < list.size(); i++) {
        String[] data = new String[7];

            data[0] = list.get(i).getName();
            data[1] = list.get(i).getEmail();
            data[2] = list.get(i).getPhone1();
            data[3] = list.get(i).getPhone2();
            data[4] = list.get(i).getGroup();
            data[5] = list.get(i).getId();

        tableModel.addRow(data);
    }
    jTable.setModel(tableModel);
}

Derzeit habe ich diese Methode verwendet, um die Tabelle nach dem Aktualisieren der Tabellendaten zu aktualisieren. Ich werde zuerst den Tisch abräumen

DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();
tableModel.setRowCount(0);

und strukturieren Sie dann das Tabellenmodell erneut um, damit die jTable aktualisiert wird. Aber ich dachte, gibt es Best Practices oder einen besseren Weg, dies zu tun?

user236501
quelle

Antworten:

118

Wenn Sie JTableüber Änderungen Ihrer Daten informiert werden möchten , verwenden Sie
tableModel.fireTableDataChanged()

Aus der Dokumentation :

Benachrichtigt alle Listener, dass sich möglicherweise alle Zellenwerte in den Zeilen der Tabelle geändert haben. Möglicherweise hat sich auch die Anzahl der Zeilen geändert, und die JTable sollte die Tabelle von Grund auf neu zeichnen. Die Struktur der Tabelle (wie in der Reihenfolge der Spalten) wird als gleich angenommen.

Peter Lang
quelle
Meinst du, ich rufe diese tableModel.fireTableDataChanged () jedes Mal auf, wenn ich aktualisiere?
user236501
3
@ newbie123: Wenn Sie nur neue Zeilen einfügen, können Sie stattdessen fireTableRowsInserted verwenden. Auf der anderen Seite sollte die Implementierung von DefaultTableModel.addRowbereits damit umgehen ... Wird Ihre Tabelle nicht aktualisiert von addRow?
Peter Lang
4
Verwenden Sie setValueAt, DefaultTableModellöst das Ereignis aus.
Peter Lang
18
Man sollte jedoch beachten, dass der Anruf auf Casting erfolgen muss javax.swing.table.AbstractTableModel, da die Schnittstelle TableModelnicht über die oben erwähnte Methode verfügt
Milan Aleksić
@ PeterLang siehe meine Frage bitte: stackoverflow.com/questions/18282753/…
Sajad
20

Der schnellere Weg für Ihren Fall ist:

    jTable.repaint(); // Repaint all the component (all Cells).

Der optimierte Weg, wenn sich eine oder wenige Zellen ändern:

    ((AbstractTableModel) jTable.getModel()).fireTableCellUpdated(x, 0); // Repaint one cell.
Daniel De León
quelle
1
Ich fand tatsächlich, dass jTable.invalidate () die Methode war, die tatsächlich ein Neuzeichnen erzwang.
Kevin Qiu
Richtig, aber die Validierungsmethode ist Teil des Layoutprozesses und wirkt sich auch auf die übergeordneten Elemente des Containers aus. Wenn Sie also das Layout wiederholen möchten, verwenden Sie es. docs.oracle.com/javase/7/docs/api/java/awt/…
Daniel De León
7

Versuche dies

public void setUpTableData() {
    DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();

    /**
    * additional code.
    **/
    tableModel.setRowCount(0);
    /**/
    ArrayList<Contact> list = new ArrayList<Contact>();
    if (!con.equals(""))
        list = sql.getContactListsByGroup(con);
    else
        list = sql.getContactLists();
    for (int i = 0; i < list.size(); i++) {
        String[] data = new String[7];

        data[0] = list.get(i).getName();
        data[1] = list.get(i).getEmail();
        data[2] = list.get(i).getPhone1();
        data[3] = list.get(i).getPhone2();
        data[4] = list.get(i).getGroup();
        data[5] = list.get(i).getId();

        tableModel.addRow(data);
    }
    jTable.setModel(tableModel);
    /**
    * additional code.
    **/
    tableModel.fireTableDataChanged();
    /**/
}
Achille
quelle
2
Sie benötigen das jTable.setModel (tableModel) am Ende nicht, da Sie das Modell der Tabelle bereits am Anfang erhalten haben.
David George
2
DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.fireTableDataChanged(); // notifies the JTable that the model has changed
Sumit Singh
quelle
3
nein, nicht ... DefaultTableModel hat dieses Ereignis implementiert und korrekt implementiert ...
mKorbel
1

Wäre es nicht besser zu verwenden java.util.Observableund dadurch java.util.Observerwird die Tabelle aktualisiert?

Tom
quelle
6
nicht, sicher nicht, tu das nicht, warum simulierte JTables eingebaute Option und aus EDT heraus
mKorbel
-4

Ich habe es so gemacht in meiner Jtable seine automatische Aktualisierung nach 300 ms;

DefaultTableModel tableModel = new DefaultTableModel(){
public boolean isCellEditable(int nRow, int nCol) {
                return false;
            }
};
JTable table = new JTable();

Timer t = new Timer(300, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                addColumns();
                remakeData(set);
                table.setModel(model);
            }
        });
        t.start();

private void addColumns() {
        model.setColumnCount(0);
        model.addColumn("NAME");
            model.addColumn("EMAIL");} 

 private void remakeData(CollectionType< Objects > name) {
    model.setRowCount(0);
    for (CollectionType Objects : name){
    String n = Object.getName();
    String e = Object.getEmail();
    model.insertRow(model.getRowCount(),new Object[] { n,e });
    }}

Ich bezweifle, dass es mit einer großen Anzahl von Objekten wie über 500 gut funktioniert. Die andere Möglichkeit besteht darin, TableModelListener in Ihrer Klasse zu implementieren, aber ich habe nicht verstanden, wie man es gut verwendet. Schauen Sie sich http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange an

nkvnkv
quelle