2009-03-04 2 views
0

Счетчик времени показывает возраст в секундах строки в таблице. В идеале, он будет обновляться один раз в секунду. Я знаю, что могу просто увеличивать соответствующие данные в модели таблицы, запускать события (по одной на строку) и т. Д. Кажется, это излишний! Есть ли лучший, более легкий способ?Эффективный способ отображения счетчика времени в ячейке JTable

ответ

2

Что вам нужно:

  • способ смоделировать «возраст» строки, в вашей модели таблицы. Это лучше всего делать неявно, поэтому вы просто сохраняете время создания строки один раз и вычисляете возраст, когда запрашивается значение ячейки (Object getValueAt (строка, столбец)).
  • A (daemon) thread, который вызывает событие изменения таблицы каждую секунду. Вам не нужно запускать одно событие для каждой строки, но вместо этого вы можете запустить событие, которое сигнализирует об обновлении целого столбца.

Вот некоторые псевдокоды для модели таблицы:

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

Смежные вопросы