Что вам нужно, это:
- способ моделировать возраст строки в вашей табличной модели. Это лучше всего делать неявно, поэтому вы просто сохраняете время создания строки один раз и вычисляете возраст, когда запрашивается значение ячейки (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 охватывает только ячейки, которые необходимо обновить (в вашем случае: только столбец с возрастом строки), это наиболее эффективный способ реализовать это.