时间计数器以秒为单位显示表中一行的年龄。理想情况下,它将每秒更新一次。我知道我可以在表模型中增加适当的数据,触发事件(每行一个)等。这似乎有点矫枉过正!有没有更好、更轻便的方法?
问问题
800 次
1 回答
2
你需要的是:
- 一种在表格模型中对行的“年龄”进行建模的方法。这最好隐式完成,因此您只需存储一次行的创建时间并计算请求单元格值时的年龄(Object getValueAt(row, column))。
- 每秒触发表更改事件的(守护程序)线程。您不必每行触发一个事件,而是可以触发一个指示整列更新的事件。
这是表模型的一些伪代码:
public Object getValueAt (int rowIndex, int columnIndex) {
// if it's the column with the 'row age', calculate the age and return it
long rowAgeMs = System.currentTimeMs() - getCreationTime(rowIndex);
// return the age in milliseconds, or a date, or a formatted time string
}
然后,表模型还应该为线程提供一个方法,因此它可以为“行年龄”列触发一个更改事件:
公共类 MyTableModel 实现 TableModel {
private final List<TableModelListener> listeners = new LinkedList<TableModelListener>();
public void addTableModelListener (TableModelListener l) {
listeners.add(l);
}
public void removeTableModelListener (TableModelListener l) {
listeners.remove(l);
}
public void updateColumn (int column) {
TableModelEvent evt = new TableModelEvent(this, 0, Math.max(0, getRowCount() - 1), column);
for (TableModelListener listener : listeners) {
listener.tableChanged(evt);
}
}
然后,该线程将每秒为“行年龄”列触发 updateColumn(..) 方法。该方法的调用应该在 EventDispatchThread 中完成,这是使用 SwingUtilities.invokeAndWait(..) 或 SwingUtilities.invokeLater(..) 完成的。
Thread rowAgeUpdater = new Thread() {
@Override
public void run () {
while (isAlive()) {
try {
long time = System.currentTimeMillis();
long sleepTime = (time / 1000 + 1) * 1000 - time;
Thread.sleep(sleepTime);
SwingUtilities.invokeAndWait(new Runnable() {
public void run () {
model.updateColumn(ROW_AGE_COLUMN_INDEX);
}
});
} catch (Exception e) {
return;
}
}
}
};
rowAgeUpdater.setDaemon(true);
rowAgeUpdater.setPriority(Thread.MIN_PRIORITY);
rowAgeUpdater.start();
只要 TableModelEvent 的粒度仅涵盖需要更新的单元格(在您的情况下:仅具有行龄的列),这是实现这一点的最有效方法。
于 2009-03-04T10:15:04.987 回答