在Vaadin中即时同步两个表

时间:2013-09-03 10:28:22

标签: java vaadin vaadin7

在我的Vaadin UI中,我有以下场景:

Table sketch

换句话说,有两个表:

  • 可编辑的“主”表
  • 不可编辑的“slave”表,但必须包含与主表相同的数据,但可能具有可能不同的排序顺序。

最终要求排除了具有相同Container的表格(根据我的理解,这可能是错误的)。

我目前所做的是附加ItemSetChangeListenerValueChangeListener,然后使用这些事件相应地更新数据。

这是当前的粗略实现(实际上在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映射所有键,但那尖叫着“滥用”。

注意:我意识到通过服务器端这样做效率较低,但在我的情况下这不是一个问题。但是,当然,基于客户端的答案也是可以的。

1 个答案:

答案 0 :(得分:3)

您可以将编辑器的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
        }
    });