JTable Bagaimana me-refresh model tabel setelah menyisipkan menghapus atau memperbarui data.

90

Ini adalah jTable saya

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

Saya akan memanggil metode ini untuk mengambil data dari database dan memasukkannya ke dalam model tabel

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

Saat ini saya menggunakan metode ini untuk menyegarkan tabel setelah memperbarui data tabel. Saya pertama-tama akan membersihkan meja

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

lalu merestrukturisasi model tabel lagi sehingga akan menyegarkan jTable. Tetapi saya berpikir apakah ada praktik terbaik atau cara yang lebih baik untuk melakukan itu?

pengguna236501
sumber

Jawaban:

119

Jika Anda ingin memberi tahu JTabletentang perubahan data Anda, gunakan
tableModel.fireTableDataChanged()

Dari dokumentasi :

Memberi tahu semua pendengar bahwa semua nilai sel di baris tabel mungkin telah berubah. Jumlah baris mungkin juga telah berubah dan JTable harus menggambar ulang tabel dari awal. Struktur tabel (seperti pada urutan kolom) diasumsikan sama.

Peter Lang
sumber
maksud Anda saya memanggil tableModel.fireTableDataChanged () ini setiap saat ketika saya melakukan pembaruan?
pengguna236501
3
@ newbie123: Jika Anda hanya menyisipkan baris baru, Anda dapat menggunakan fireTableRowsInserted sebagai gantinya. Di sisi lain, implementasi DefaultTableModel.addRowseharusnya sudah menangani itu ... Bukankah tabel Anda di-refresh addRow?
Peter Lang
4
Gunakan setValueAt, DefaultTableModelaktifkan acara tersebut.
Peter Lang
19
Seseorang harus memperhatikan bahwa panggilan harus dilakukan saat dicor javax.swing.table.AbstractTableModel, karena antarmuka TableModeltidak memiliki metode yang disebutkan di atas
Milan Aleksić
@PeterLang lihat pertanyaan saya: stackoverflow.com/questions/18282753/…
Sajad
20

Cara tercepat untuk kasus Anda adalah:

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

Cara yang dioptimalkan ketika satu atau beberapa sel berubah:

    ((AbstractTableModel) jTable.getModel()).fireTableCellUpdated(x, 0); // Repaint one cell.
Daniel De León
sumber
1
Saya benar-benar menemukan bahwa jTable.invalidate () adalah metode yang benar-benar memaksa penggambaran ulang.
Kevin Qiu
Benar, tetapi metode validasi adalah bagian dari proses tata letak, dan memengaruhi induk penampung juga. Jadi jika Anda membutuhkan tata letak ulang, gunakanlah. docs.oracle.com/javase/7/docs/api/java/awt/…
Daniel De León
8

coba ini

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
sumber
2
Anda tidak memerlukan jTable.setModel (tableModel) di akhir karena Anda sudah mendapatkan model Tabel di awal.
David George
2
DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.fireTableDataChanged(); // notifies the JTable that the model has changed
Sumit Singh
sumber
3
tidak, bukan ... DefaultTableModel telah mengimplementasikan acara ini, dan mengimplementasikan dengan benar ...
mKorbel
1

Bukankah lebih baik menggunakan java.util.Observabledan java.util.Observeritu akan menyebabkan tabel diperbarui?

tom
sumber
7
tidak, tentu tidak, jangan lakukan itu, mengapa mensimulasikan opsi
bawaan
-4

Saya melakukannya seperti ini di Jtable saya dengan autorefreshing setelah 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 });
    }}

Saya ragu itu akan berhasil dengan sejumlah besar objek seperti lebih dari 500, hanya cara lain adalah dengan mengimplementasikan TableModelListener di kelas Anda, tetapi saya tidak mengerti bagaimana menggunakannya dengan baik. lihat http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

nkvnkv
sumber