我有一个合理的简单JTable
,我想每秒更新一次。
为此,我发现您应该使用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
,以防万一我以某种方式犯错了计时器。我究竟做错了什么? 最佳答案
您使用的DefaultTableModel
从Vector
数组创建一个Object
并将其用作其数据:
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 });
或搜索与名称匹配的行,然后更新该行:
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);
}