我有一个合理的简单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
只是因为我以某种方式错误地使用了计时器。我做错了什么?
答案 0 :(得分:2)
您使用的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);
}