Reputation: 2258
A time counter shows the age in seconds of a row in the table. Ideally, it would be updated once per second. I know I can just increment the appropriate data in the table model, fire the events (one per row), etc. It seems like overkill! Is there a better, lighter way?
Upvotes: 0
Views: 848
Reputation: 15706
What you need is:
Here's some pseudocode for the table model:
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
}
The table model should then also offer a method for the thread, so it can fire a change event for the 'row age' column:
public class MyTableModel implements 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);
}
}
The thread would then just trigger the updateColumn(..) method each second for the 'row age' column. The invocation of this method should be done in the EventDispatchThread, this is done using SwingUtilities.invokeAndWait(..) or 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();
As long as the granularity of the TableModelEvent only covers the cells that need to be updated (in your case: only the column with the row age), it's the most efficient way to realize this.
Upvotes: 2