2017-03-16 62 views
1

我有一個合理的簡單JTable,我想每秒更新一次。如何正確觸發`fireTableDataChanged`

要做到這一點,我發現你應該使用fireTableDataChanged(),但是,經過多次嘗試,我仍然無法讓它工作。

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.Timer; 
import javax.swing.table.DefaultTableModel; 

@SuppressWarnings("serial") 
public class Changer extends JFrame { 
    int phils = 1; 
    int daves = 2; 
    int bobs = 3; 
    String[] cols = {"Name", "Num"}; 
    Object[][] data = {{"Phil", phils}, 
         {"Dave", daves}, 
         {"Bob", bobs}}; 
    DefaultTableModel dm = new DefaultTableModel(data, cols); 
    JTable table = new JTable(dm); 

    public Changer() { 
     super("Changer"); 

     JPanel p = new JPanel(); 
     p.add(new JScrollPane(table)); 
     add(p); 
     pack(); 
     setVisible(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     Timer t = new Timer(1000, new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       phils++; 
       daves++; 
       bobs++; 
       data = new Object[][] {{"Phil", phils}, 
          {"Dave", daves}, 
          {"Bob", bobs}}; 
       dm.fireTableDataChanged(); 
       repaint(); 
       revalidate(); 
       table.repaint(); 
       table.revalidate(); 

       System.out.println(phils + ", " + daves + ", " + bobs); 
      } 
     }); 

     t.start(); 
    } 

    public static void main(String[] args) { 
     new Changer(); 
    } 
} 

首先我不得不

Timer t = new Timer(1000, new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     phils++; 
     daves++; 
     bobs++; 

     dm.fireTableDataChanged(); 
    } 
}); 

由於文檔似乎表明,如果值更新它的工作。

然後我試圖

Timer t = new Timer(1000, new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     phils++; 
     daves++; 
     bobs++; 

     data = new Object[][] {{"Phil", phils}, 
       {"Dave", daves}, 
       {"Bob", bobs}}; 
     dm.fireTableDataChanged(); 
    } 
}); 

,看看我是否有物理更新變量data

最後,我添加了所有的驗證和重新繪製,看看是否會有所作爲,並且System.out.println只是因爲我以某種方式犯了計時器錯誤。我究竟做錯了什麼?

回答

2

DefaultTableModel你正在使用從Object陣列創建Vector並使用它作爲它的數據:

protected static Vector convertToVector(Object[][] anArray) { 
     if (anArray == null) { 
      return null; 
     } 
     Vector<Vector> v = new Vector<Vector>(anArray.length); 
     for (Object[] o : anArray) { 
      v.addElement(convertToVector(o)); 
     } 
     return v; 
    } 

這意味着更換陣列(甚至修改其內容)不會神奇地反映對模型的任何改變。

你可以做什麼之前,呼籲dm.fireTableDataChanged()要麼

更換模式

dm.setDataVector(data, cols); 

的數據或刪除所有行和插入新

while(dm.getRowCount()>0){ 
     dm.removeRow(0); 
} 
dm.addRow(new Object[] {"Phil", phils }); 
dm.addRow(new Object[] {"Dave", daves }); 
dm.addRow(new Object[] {"Bob", bobs }); 

或者搜索與t匹配的行他的名字,然後更新該行:

updateRow(new Object[] {"Phil", phils }); 
updateRow(new Object[] {"Dave", daves }); 
updateRow(new Object[] {"Bob", bobs }); 

這種updateRow方法從Java JTable update row很大程度上啓發:

private void updateRow(Object[] data) { 

     String userName = data[0].toString(); 
     for (int i = 0; i < dm.getRowCount(); i++) 
      if (dm.getValueAt(i, 0).equals(userName)) 
       for (int j = 1; j < data.length; j++) 
        dm.setValueAt(data[j], i, j); 
    } 
+1

'dm.setDataVector(數據的cols);'做的感謝 – Dan