私の Vaadin UI には、次のシナリオがあります。
つまり、次の 2 つのテーブルがあります。
- 編集可能な「マスター」テーブル
- 編集不可の「スレーブ」テーブルですが、マスター テーブルと同じデータを含む必要がありますが、ソート順が異なる可能性があります。
最終的な要件は、テーブルが同じであることを排除します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
すべてのキーのマッピングを使用することでしたが、それは「悪用」を叫んでいます。
注:サーバー側でこれを行うと効率が悪いことはわかっていますが、私の場合は問題ありません。ただし、もちろん、クライアント側ベースの回答も問題ありません。