JTable Come aggiornare il modello di tabella dopo l'inserimento, eliminare o aggiornare i dati.


89

Questo è il mio 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;
}

Chiamerò questo metodo per recuperare i dati dal database e inserirli nel modello di tabella

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);
}

Attualmente stavo usando questo metodo per aggiornare la tabella dopo aver aggiornato i dati della tabella. Per prima cosa spareccherò il tavolo

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

e quindi ristrutturare di nuovo il modello di tabella in modo da aggiornare jTable. Ma stavo pensando che ci sono buone pratiche o un modo migliore per farlo?

Risposte:


119

Se vuoi avvisarti JTabledelle modifiche dei tuoi dati, usa
tableModel.fireTableDataChanged()

Dalla documentazione :

Notifica a tutti i listener che tutti i valori delle celle nelle righe della tabella potrebbero essere cambiati. Anche il numero di righe potrebbe essere cambiato e JTable dovrebbe ridisegnare la tabella da zero. Si presume che la struttura della tabella (come nell'ordine delle colonne) sia la stessa.


vuoi dire che chiamo questo tableModel.fireTableDataChanged () ogni volta che faccio l'aggiornamento?
user236501

3
@ newbie123: se inserisci solo nuove righe, puoi usare fireTableRowsInserted invece. D'altra parte, l'implementazione di DefaultTableModel.addRowdovrebbe già gestirlo ... La tua tabella non è stata aggiornata da addRow?
Peter Lang

4
Usa setValueAt, DefaultTableModelaccende l'evento.
Peter Lang

18
Va notato però che la chiamata deve essere effettuata su cast javax.swing.table.AbstractTableModel, poiché l'interfaccia TableModelnon ha il metodo sopra menzionato
Milan Aleksić

@PeterLang vedere la mia domanda per favore: stackoverflow.com/questions/18282753/...
Sajad

20

Il modo più veloce per il tuo caso è:

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

Il modo ottimizzato quando una o poche celle cambiano:

    ((AbstractTableModel) jTable.getModel()).fireTableCellUpdated(x, 0); // Repaint one cell.

1
In realtà ho scoperto che jTable.invalidate () era il metodo che in realtà ha forzato un ridisegno.
Kevin Qiu

Giusto, ma il metodo di convalida fa parte del processo di layout e influisce anche sui genitori del contenitore. Quindi, se hai bisogno di rifare il layout, usalo. docs.oracle.com/javase/7/docs/api/java/awt/…
Daniel De León

7

prova questo

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();
    /**/
}

2
Non hai bisogno di jTable.setModel (tableModel) alla fine poiché hai già ottenuto il modello della tabella all'inizio.
David George

2
DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.fireTableDataChanged(); // notifies the JTable that the model has changed

3
no, non ... DefaultTableModel ha implementato questo evento e implementato correttamente ...
mKorbel

1

Non sarebbe meglio usare java.util.Observablee java.util.Observerciò causerà l'aggiornamento della tabella?


6
no, certo no, non farlo, perché l'opzione incorporata di JTable simulata e fuori da EDT
mKorbel

-4

L'ho fatto in questo modo nel mio Jtable con l'aggiornamento automatico dopo 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 });
    }}

Dubito che andrà bene con un gran numero di oggetti come oltre 500, solo un altro modo è implementare TableModelListener nella tua classe, ma non ho capito come usarlo bene. guarda http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.