jgoodies bindings + объединение частых изменений

У меня есть Java-приложение, которое обновляет данные с переменной скоростью (полученные из довольно высокоскоростного потока данных вне моего контроля, но до 120 Кбайт / с), и я хотел бы отображать статистику, такую ​​как количество полученных байтов / пакетов, используя диалоговое окно.

Я изучаю привязки JGoodies и получил кое-что предварительно работающее с искусственными данными, полученными по низким ставкам.

Что я хотел бы сделать, примерно, это:

  1. сделать класс бобов примерно таким:

    public class Statistics
    {
      private int bytes;
      private int goodPackets;
      private int badPackets;
      private int totalPackets;
    
      public int getBytes() { return bytes; }
      public int getGoodPackets() { return goodPackets; }
      public int getBadPackets() { return badPackets; }
      public int getTotalPackets() { return totalPackets; }
    
      public void update(/* TBD */) { /* updates the fields appropriately */ }
      public Statistics() { bytes=goodPackets=badPackets=totalPackets=0; }
    }
    
    Statistics stats;
    
  2. привязать 4 поля к элементам в моем графическом интерфейсе

  3. быть в состоянии звонить stats.update() с любой скоростью, необходимой в моем основном потоке приложений, где вызов "update" запускает прослушиватели изменений GUI
  4. сделать так, чтобы графический интерфейс "автоматически" обновлялся с более низкой частотой, которую я могу указать, примерно 5–20 Гц, чтобы он не был перегружен множеством инициированных событий.

Есть ли подходящий механизм, который позволил бы мне делать то, что я хочу? Я смотрю на JGoodies DelayedReadValueModel, но я не совсем понимаю, как его использовать.

Если бы мне пришлось делать это вручную, я думаю, что я, вероятно, сделал бы:

  1. иметь зеркальную копию статистики и добавить какой-либо флаг обновления, а также ссылку с оригинала на зеркальную копию и тайм-аут таймера
  2. когда update() метод вызывается, установить флаг обновления и вызвать метод, как maybePropagate()
  3. maybePropagate(): если тайм-аут таймера идет, или ссылка на зеркальную копию пуста, он ничего не делает; в противном случае он запускает тайм-аут и отправляет обновленные данные в зеркальную копию и очищает флаг обновления
  4. по истечении времени ожидания таймера, если установлен флаг обновления и ссылка на зеркальную копию не равна нулю, он отправляет обновленные данные в зеркальную копию и очищает флаг обновления
  5. Реализовав предыдущие 4 элемента, моя зеркальная копия имеет максимальную скорость обновления, и поэтому я могу просто привязать элементы GUI к полям зеркальной копии с помощью обычного JGoodies BeanAdapter.

Какие-либо предложения?

2 ответа

Хотя JGoodies Binding решает эту проблему с классами Delayed*, вы можете рассмотреть возможность использования подхода со стандартными функциями Swing.

Если вы используете SwingWorker, вы можете публиковать элементы в фоновом режиме и обрабатывать их в EDT. Процесс SwingWorker будет получать порции опубликованных данных и сокращать количество изменений EDT.

Если у вас есть модель представления для вашей статистики, код привязки может выглядеть следующим образом:

ValueModel bytesModel = statsPresentationModel.getModel("bytes");
label = BasicComponentFactory.createLabel(bytesModel);

Теперь, чтобы отложить обновление, вы можете обернуть модель значения для байтового поля:

ValueModel bytesModel = new DelayedReadValueModel(statsPresentationModel.getModel("bytes"));
label = BasicComponentFactory.createLabel(bytesModel);
Другие вопросы по тегам