JTable Cách làm mới mô hình bảng sau khi chèn xóa hoặc cập nhật dữ liệu.


89

Đây là jTable của tôi

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

Tôi sẽ gọi phương thức này để lấy dữ liệu từ cơ sở dữ liệu và đưa nó vào mô hình bảng

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

Hiện tại tôi đang sử dụng phương pháp này để làm mới bảng sau khi cập nhật dữ liệu bảng. Đầu tiên tôi sẽ dọn bàn

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

và sau đó cấu trúc lại mô hình bảng để nó sẽ làm mới jTable. Nhưng tôi đang nghĩ có cách nào tốt nhất hoặc cách tốt hơn để làm điều đó không?

Câu trả lời:


119

Nếu bạn muốn thông báo JTablevề những thay đổi của dữ liệu, hãy sử dụng
tableModel.fireTableDataChanged()

Từ tài liệu :

Thông báo cho tất cả người nghe rằng tất cả các giá trị ô trong các hàng của bảng có thể đã thay đổi. Số lượng hàng cũng có thể đã thay đổi và JTable sẽ vẽ lại bảng từ đầu. Cấu trúc của bảng (theo thứ tự của các cột) được giả định là giống nhau.


Ý của bạn là tôi luôn gọi tableModel.fireTableDataChanged () này khi tôi cập nhật?
user236501

3
@ newbie123: Nếu bạn chỉ chèn các dòng mới, bạn có thể sử dụng fireTableRowsInserted để thay thế. Mặt khác, việc thực hiện DefaultTableModel.addRownên đã xử lý điều đó ... Bảng của bạn không được làm mới bởi addRow?
Peter Lang

4
Sử dụng setValueAt, DefaultTableModelkích hoạt sự kiện.
Peter Lang

18
Người ta phải nhận thấy rằng mặc dù cuộc gọi phải được thực hiện trên đúc javax.swing.table.AbstractTableModel, vì giao diện TableModelkhông có phương pháp nêu trên
Milan Aleksić

@PeterLang vui lòng xem câu hỏi của tôi: stackoverflow.com/questions/18282753/…
Sajad

20

Cách nhanh hơn cho trường hợp của bạn là:

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

Cách được tối ưu hóa khi một hoặc một vài ô thay đổi:

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

1
Tôi thực sự thấy rằng jTable.invalidate () là phương thức thực sự buộc phải vẽ lại.
Kevin Qiu

Đúng vậy, nhưng phương thức xác thực là một phần của quá trình bố trí và cũng ảnh hưởng đến cha mẹ của vùng chứa. Vì vậy, nếu bạn cần làm lại bố cục, hãy sử dụng nó. docs.oracle.com/javase/7/docs/api/java/awt/…
Daniel De León

7

thử đi

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
Bạn không cần jTable.setModel (tableModel) ở cuối vì bạn đã có mô hình của Table ở đầu.
David George

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

3
không, không ... DefaultTableModel đã thực hiện sự kiện này, và thực hiện một cách chính xác ...
mKorbel

1

Nó sẽ không tốt hơn khi sử dụng java.util.Observablejava.util.Observerđiều đó sẽ khiến bảng cập nhật?


6
không, chắc chắn không, không làm điều đó, tại sao mô phỏng JTable tích hợp trong lựa chọn và ra từ EDT
mKorbel

-4

Tôi đã làm nó như thế này trong Jtable của tôi, nó tự động làm mới sau 300 mili giây;

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

Tôi nghi ngờ nó sẽ hoạt động tốt với số lượng lớn các đối tượng như hơn 500, chỉ có cách khác là triển khai TableModelListener trong lớp của bạn, nhưng tôi không hiểu cách sử dụng nó tốt. xem tại http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.