Здравствуйте, cuba ver. 7.2.11
Две сущности: invoice, invoiceItem, отношение - композиция, один ко многим. Сгенерирован экран редактирования для invoice, в таблице invoiceItems генерируемые колонки:
<table id="invoiceItemsTable" dataContainer="invoiceItemsDc" width="100%" height="600px" editable="true">
...
<columns>
<column id="name" editable="true" generator="newNameCell"/>
<column id="price" editable="true" generator="newPriceCell"/>
<column id="nds" editable="true" generator="newNdsCell"/>
<column id="currency" editable="true" generator="newCurrencyCell"/>
<column id="quantity" editable="true"/>
</columns>
<buttonsPanel>
<checkBox id="readOnlyField" caption="Read only"/>
...
</buttonsPanel>
</table>
Пример генераторов:
fun newNameCell(entity: InvoiceItem): Component {
val field = uiComponents.create(TextField.NAME) as TextField<String>
setValueSource(field, entity, "name")
field.setWidthFull()
return field
}
private fun setValueSource(field: Component, entity: InvoiceItem, property: String) {
if (field is HasValueSource<*>) {
val ic = invoiceItemsTable.getInstanceContainer(entity)
(field as HasValueSource<*>).valueSource = ContainerValueSource(ic, property)
}
}
Так же добавлен чекбокс, который переключает таблицу в режим просмотра\редактирования:
private val columnsGeneratorMap = hashMapOf<String, Function<InvoiceItem, Component>>(
"name" to Function { newNameCell(it) },
"price" to Function { newPriceCell(it) },
"nds" to Function { newNdsCell(it) },
"currency" to Function { newCurrencyCell(it) }
)
@Subscribe("readOnlyField")
private fun onReadOnlyFieldValueChange(event: HasValue.ValueChangeEvent<Boolean>) {
changeReadOnly(event.value!!)
}
fun changeReadOnly(readOnly: Boolean) {
invoiceItemsTable.isEditable = !readOnly
if (readOnly) {
columnsGeneratorMap.keys.forEach { invoiceItemsTable.removeGeneratedColumn(it) }
} else {
columnsGeneratorMap.forEach { pair ->
invoiceItemsTable.addGeneratedColumn(pair.key) {
pair.value.apply(it)
}
}
}
}
И переопределен экшен создания нового invoiceItem:
@Subscribe("invoiceItemsTable.create")
private fun onInvoiceItemsTableCreate(event: Action.ActionPerformedEvent) {
if (!invoiceItemsTable.isEditable) {
changeReadOnly(false)
}
var newItem: InvoiceItem = metadata.create(InvoiceItem::class.java)
newItem.invoice = editedEntity
newItem = dataContext.merge(newItem)
invoiceItemsDc.mutableItems += newItem
invoiceItemsTable.setSelected(newItem)
}
1.При первоначальном открытии редактора, поведение при переключении табом нормальное:
https://recordit.co/DD4k74AKDR
После переключения режима редактирования, фокус табом сбивается:
https://recordit.co/HichU1Owjv
2. Для генерируемой колонки price добавил кэш компонента, в котором обновляю valueSource:
//HashMap<Pair<entityId, columnId>, field>
private val fields = HashMap<Pair<UUID, String>, Component>()
fun newPriceCell(entity: InvoiceItem): Component {
val field = fields.computeIfAbsent(Pair(entity.id, "price")) {
val field = uiComponents.create(TextField.NAME) as TextField<BigDecimal>
field.setWidthFull()
return@computeIfAbsent field
}
setValueSource(field, entity, "price")
return field
}
Значения, вводимые в эту колонку после переключения режима редактирования применяется через раз:
https://recordit.co/qc9AXj1WJt
Демо проект:
tableeditor.rar (76.5 КБ)