2010-07-05 19 views
79

Đây là tôi JTableJTable 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.

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 pháp này để lấy dữ liệu từ cơ sở dữ liệu và đặt 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 nay tôi đã sử dụng phương pháp này để làm mới bảng sau khi cập nhật bảng dữ liệu. Trước tiên, tôi sẽ xóa bảng

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

và sau đó cấu trúc lại mô hình bảng để làm mới jTable. Nhưng tôi đã suy nghĩ là có bất kỳ thực hành tốt nhất hoặc cách tốt hơn để làm điều đó?

Trả lời

101

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

Từ documentation:

Thông báo cho tất cả người nghe rằng tất cả các giá trị của ô theo hàng của bảng có thể đã thay đổi. Số 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ác cột) được giả định là giống nhau.

+0

gì bạn có nghĩa tôi gọi tableModel.fireTableDataChanged() này mỗi khi tôi cập nhật? – user236501

+3

@ newbie123: Nếu bạn chỉ chèn dòng mới, bạn có thể sử dụng [fireTableRowsInserted] (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/table/AbstractTableModel.html#fireTableRowsInserted% 28%, 20%% 29%). Mặt khác, việc thực hiện 'DefaultTableModel.addRow' nên đã xử lý ... Bảng của bạn không được làm mới bằng' addRow'? –

+0

Tôi đang sử dụng addRow nó hoạt động nhưng làm thế nào về cập nhật? – user236501

-2

Tôi đã làm như thế này trong Jtable tính năng tự động của nó 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ẽ làm tốt với số lượng lớn của các đối tượng như trên 500, chỉ có cách nào khác là thực hiện TableModelListener trong lớp học của bạn, nhưng tôi không hiểu làm thế nào để sử dụng nó tốt. nhìn vào http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

1

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

+5

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

16

Cách nhanh hơn đối với trường hợp của bạn là:

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

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

((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 vẽ lại. –

+0

Phải, nhưng phương thức xác thực là một phần của quy trình bố cục 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ó. http://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#invalidate() –

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

không, không ... DefaultTableModel đã triển khai sự kiện này và triển khai chính xác ... – mKorbel

5

thử này

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 khi bạn đã có được mô hình của Bảng lúc bắt đầu. –