Как синхронизировать модель Swing с быстро изменяющейся “реальной” моделью?

Brainf*ck

+++++
>+<[[->>>>+<<<<]>>>>[-<<<<+>>+>>]<<<<>[->>+<<]<>>>[-<[->>+<<]>>[-<<+<+>>>]<]<[-]><<<-]

записан Michael Reitzenstein.

16
задан Joonas Pulakka 16 November 2009 в 14:08
поделиться

3 ответа

Я могу порекомендовать следующий подход:

  • Поместите события, которые должны изменить таблицу, в очередь «ожидающих событий», и когда событие помещается в очередь , а очередь пуста , затем вызовите поток отправки событий, чтобы очистить очередь от всех события и обновить модель таблицы. Эта оптимизация означает , что вы больше не вызываете поток отправки событий для каждого полученного события , что решает проблему потока отправки событий, не успевающего за основным потоком событий.
  • Избегайте создания нового Runnable при вызове потока диспетчеризации событий с использованием внутреннего класса без сохранения состояния для очистки очереди ожидающих событий в реализации вашей панели таблицы.
  • Дополнительная дополнительная оптимизация: При опорожнении очереди ожидающих событий минимизируйте количество запускаемых событий обновления таблицы, запомнив, какие строки таблицы необходимо перекрасить, и затем запускайте одно событие (или одно событие на строку) после обработки всех событий.

Пример кода

public class MyStockPanel extends JPanel {
  private final BlockingQueue<StockEvent> stockEvents;

  // Runnable invoked on event dispatch thread and responsible for applying any
  // pending events to the table model.
  private final Runnable processEventsRunnable = new Runnable() {
    public void run() {
      StockEvent evt;

      while ((evt = stockEvents.poll() != null) {
        // Update table model and fire table event.
        // Could optimise here by firing a single table changed event
        // when the queue is empty if processing a large #events.
      }
    }
  }

  // Called by thread other than event dispatch thread.  Adds event to
  // "pending" queue ready to be processed.
  public void addStockEvent(StockEvent evt) {
    stockEvents.add(evt);

    // Optimisation 1: Only invoke EDT if the queue was previously empty before
    // adding this event.  If the size is 0 at this point then the EDT must have
    // already been active and removed the event from the queue, and if the size
    // is > 0 we know that the EDT must have already been invoked in a previous
    // method call but not yet drained the queue (i.e. so no need to invoke it
    // again).
    if (stockEvents.size() == 1) {
      // Optimisation 2: Do not create a new Runnable each time but use a stateless
      // inner class to drain the queue and update the table model.
      SwingUtilities.invokeLater(processEventsRunnable);
    }
  }
}
11
ответ дан 30 November 2019 в 22:49
поделиться

Насколько я понимаю, вы не хотите реализовывать интерфейсы модели Swing в своей реальной модели , вы? Можете ли вы реализовать модель Swing как «представление» над частью реальной модели? Он преобразует свой доступ для чтения getValueAt () в вызовы реальной модели, а реальная модель будет уведомлять модель Swing об изменениях, либо предоставляя список изменений, либо предполагая, что модель Swing позаботится о запросе новых значений все, что он сейчас показывает.

2
ответ дан 30 November 2019 в 22:49
поделиться

Обычный подход - посылать какие-то «сигналы», которые пользовательский интерфейс слушает. В своем коде я часто использую центральный диспетчер, который отправляет сигналы, содержащие измененный объект, имя поля / свойства, а также старое и новое значение. Сигнал не отправляется для случая oldValue.equals (newValue) или oldValue.compareTo (newValue) == 0 (последний для дат и BigDecimal ).

Затем поток пользовательского интерфейса регистрирует слушателя для всех сигналов. Затем он проверяет объект и имя, а затем преобразует это в изменение в пользовательском интерфейсе, которое выполняется с помощью asyncExec () .

Вы можете превратить это в прослушиватель для каждого объекта и зарегистрировать каждый элемент пользовательского интерфейса сам к модели. Но я обнаружил, что это просто распространяет код повсюду.

2
ответ дан 30 November 2019 в 22:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: