2010-07-05 163 views
79

這是我的JTableJTable如何在插入刪除或更新數據後刷新表模型。

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

我會調用這個方法從數據庫中檢索數據,並把它放入臺式

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

目前我就是用這個方法來刷新表更新後表數據。我將首先清除表格

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

然後再次重構表模型,以便刷新jTable。但我在想有沒有最佳做法或更好的方法來做到這一點?

回答

101

如果你想通知你JTable有關數據的更改,請使用
tableModel.fireTableDataChanged()

documentation

通知,在表中的所有行單元格值可能已改變了所有的聽衆。行數也可能已更改,JTable應從頭開始重新繪製表。表格的結構(按照列的順序)假定是相同的。

+0

你的意思我每次更新時都會調用這個tableModel.fireTableDataChanged()? – user236501 2010-07-05 11:57:16

+3

@ newbie123:如果只插入新行,則可以使用[fireTableRowsInserted](http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/table/AbstractTableModel.html#fireTableRowsInserted% 28int,%20int%29)。另一方面,'DefaultTableModel.addRow'的實現應該已經可以處理...不是用'addRow'刷新表嗎? – 2010-07-05 11:59:39

+0

我正在使用addRow它的作品,但如何更新? – user236501 2010-07-05 12:24:47

-2

我在我的Jtable中做了這樣的事情,它在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 }); 
    }} 

我懷疑它會做的好有大量像500的對象,只是另一種方式是在你的類實現TableModelListener,但我不知道如何使用它做好。看看http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

1

使用java.util.Observablejava.util.Observer會導致表更新會不會更好?

+5

不是,當然不是,不這樣做,爲什麼模擬JTable的內置選項和出自EDT – mKorbel 2011-10-16 12:10:55

16

您的情況下,更快的方法是:

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

優化的方式,當一個或幾個小區改變:

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

我實際上發現jTable .invalidate()是實際強制重繪的方法。 – 2013-06-06 18:36:39

+0

沒錯,但驗證方法是佈局過程的一部分,也會影響容器的父母。因此,如果您需要重做佈局,請使用它。 http://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#invalidate() – 2013-06-07 01:23:26

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

不,不... DefaultTableModel已實現此事件,並正確實施... – mKorbel 2012-08-21 10:50:15

5

試試這個

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

您最後不需要jTable.setModel(tableModel),因爲您已經在開始時獲得了Table的模型。 – 2014-05-13 08:18:35

相關問題