时间计数器显示表中一行的寿命(以秒为单位)。理想情况下,它每秒更新一次。我知道我可以在表模型中增加适当的数据,触发事件(每行一个)等。似乎有点矫枉过正了!有没有更好、更轻松的方法?

有帮助吗?

解决方案

你需要的是:

  • 一种对表模型中行的“年龄”进行建模的方法。最好隐式完成此操作,因此您只需存储一次行的创建时间,并在请求单元格值时计算年龄 (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 的粒度仅覆盖需要更新的单元格(在您的情况下:仅具有行龄的列),这是实现这一点的最有效方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top