2

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

表草图

换句话说,有两个表:

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

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

我目前所做的是附加 anItemSetChangeListener和 a 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映射所有键,但这尖叫着“滥用”。

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

4

1 回答 1

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
        }
    });
于 2013-09-06T13:24:58.143 回答