Эффективный способ отображения счетчика времени в ячейке JTable - PullRequest
0 голосов
/ 04 марта 2009

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

1 Ответ

2 голосов
/ 04 марта 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...