Мгновенная синхронизация двух таблиц в Vaadin

В моем интерфейсе Vaadin у меня есть следующий сценарий:

Эскиз таблицы

Другими словами, есть две таблицы:

  • "основная" таблица, которую можно редактировать,
  • «подчиненная» таблица, которая не редактируется, но должна содержать те же данные, что и основная таблица, но с потенциально другим порядком сортировки.

Последнее требование не позволяет таблицам иметь одинаковый Container (в моем понимании, что может быть неправильным).

В настоящее время я прикрепляю ItemSetChangeListener и ValueChangeListener и использую события для соответствующего обновления данных.

Вот текущая грубая реализация (на самом деле в Scala, но я надеюсь, что она достаточно читабельна, если нет, прокомментируйте):

class DataTableSynchronizer(val master: Table, val slave: Table) extends ItemSetChangeListener with ValueChangeListener {

  def init():Unit = {
    master.addItemSetChangeListener(this)
    containerMaster.addListener(this.asInstanceOf[ValueChangeListener])

  }

  private def containerOf(t: Table) = t.getContainerDataSource().asInstanceOf[IndexedContainer]

  private def containerMaster = containerOf(master)

  private def containerSlave = containerOf(slave)

  override def containerItemSetChange(event: ItemSetChangeEvent) {
    //handling 
    //remove all items that have been deleted
    for(toDel <- containerSlave.getItemIds().filterNot(containerMaster.containsId(_))) {
      containerSlave.removeItem(toDel)
    }

    //add new items to the start
    for(toAdd <- containerMaster.getItemIds().filterNot(containerSlave.containsId(_))) {
      containerSlave.addItem(toAdd)
    }
    slave.validate();
  }

  override def valueChange(event: ValueChangeEvent) = {
      updateValuesInResults()
  }

  private def updateValuesInResults(): Unit = {
    //update all values in the "slave" table from the "master" table
    for((itemData,itemResults) <- containerMaster.getItemIds().map(id => (containerMaster.getItem(id),containerSlave.getItem(id)))) {
      for(propId <- itemData.getItemPropertyIds()) {
        itemResults.getItemProperty(propId).asInstanceOf[Property[Any]].setValue(itemData.getItemProperty(propId).getValue().asInstanceOf[Any])
      }
    }
  }

}

Однако моя проблема заключается в том, что мне нужно, чтобы данные синхронизировались постоянно, поскольку пользователь вводит, чего не происходит из-за того, что соответствующие события отправляются только после завершения некоторой операции (добавляется строка и т. Д. .).

Как мне решить эту проблему, например, как мне заставить события генерироваться достаточно часто, чтобы обеспечить непрерывную синхронизацию? Единственная идея, которая у меня была, заключалась в том, чтобы использовать ActionListener сопоставление всех ключей, но это кричит «злоупотребление».

Примечание. Я понимаю, что делать это на стороне сервера менее эффективно, но в моем случае это не проблема. Тем не менее, ответы на стороне клиента, конечно же, тоже допустимы.


person mikołak    schedule 03.09.2013    source источник


Ответы (1)


Вы можете установить TextChangeEventMode редактора на EAGER и обрабатывать отдельные нажатия клавиш в прослушивателе событий:

    TextField textField = ...;
    textField.setTextChangeEventMode(TextChangeEventMode.EAGER);
    textField.addTextChangeListener(new TextChangeListener() {
        @Override
        public void textChange(TextChangeEvent event) {
            String text = event.getText();
            // sync with other component
        }
    });
person Ingo Kegel    schedule 06.09.2013
comment
Спасибо! У меня нет доступа к коду приложения, я проверю и приму его, как только смогу. Кстати, правильно ли я понимаю, что для этой цели мне нужно будет предоставить специальный TableFieldFactory? - person mikołak; 07.09.2013
comment
Да, вы должны сделать это, чтобы предоставить собственную реализацию текстового поля. - person Ingo Kegel; 07.09.2013