Sie können entweder Ihre eigene cellfactory implementieren und eine Zelle zurückgeben, die im Bearbeitungsmodus ein an ein ViewModel gebundenes Textfeld anzeigt, und eine Beschriftung, falls dies nicht der Fall ist. Alternativ, wenn Sie mit immer die Anzeige einer Textfeld fein sind, können Sie cellFormat
und binden das aktuelle Element zu einem ItemModel verwenden können, so dass Sie die Validierung anhängen können:
class ItemModel(item: Item) : ItemViewModel<Item>(item) {
val name = bind(Item::nameProperty)
val number = bind(Item::numberProperty)
}
class MainView : View("Example") {
val items = listOf(Item("One", 1), Item("Two", 2)).observable()
override val root = vbox {
tableview(items) {
column("Name", Item::nameProperty).makeEditable()
column("Number", Item::numberProperty).cellFormat {
val model = ItemModel(rowItem)
graphic = textfield(model.number, NumberStringConverter()) {
validator {
if (model.number.value == 123) error("Invalid number") else null
}
}
}
}
}
}
Es wird wie folgt aussehen:
Während es funktioniert, ist es eine Art verschwenderisch, da die Knoten häufig neu erstellt werden. Ich würde Ansatz Nummer eins empfehlen, wenn Leistung ein Anliegen ist, bis wir cellFragment
Unterstützung für TableView wie wir für ListView haben.
EDIT: Ich implementierte cellFragment
Unterstützung, so ist es möglich, eine robustere Lösung zu schaffen, die ein Etikett, wenn sie nicht in den Bearbeitungsmodus und eine Validierung von Textfeld zeigen wird, wenn Sie den Bearbeitungsmodus aufzurufen.
class ItemModel : ItemViewModel<Item>() {
val name = bind(Item::nameProperty)
val number = bind(Item::numberProperty)
}
class MainView : View("Example") {
val items = listOf(Item("One", 1), Item("Two", 2)).observable()
override val root = vbox {
tableview(items) {
column("Name", Item::nameProperty).makeEditable()
column("Number", Item::numberProperty).cellFragment(NumberEditor::class)
}
}
}
class NumberEditor : TableCellFragment<Item, Number>() {
// Bind our ItemModel to the rowItemProperty, which points to the current Item
val model = ItemModel().bindToRowItem(this)
override val root = stackpane {
textfield(model.number, NumberStringConverter()) {
removeWhen(editingProperty.not())
validator {
if (model.number.value == 123L) error("Invalid number") else null
}
// Call cell.commitEdit() only if validation passes
action {
if (model.commit()) {
cell?.commitEdit(model.number.value)
}
}
}
// Label is visible when not in edit mode, and always shows committed value (itemProperty)
label(itemProperty) {
removeWhen(editingProperty)
}
}
// Make sure we rollback our model to avoid showing the last failed edit
override fun startEdit() {
model.rollback()
}
}
Dies ist ab TornadoFX 1.7.9 möglich.
Ich aktualisierte die Antwort mit einer robusteren Lösung mit einem TableCellFragment, das in TornadoFX 1.7.9 eingeführt wird :) –
wow, danke Edvin, sieht für meinen Fall perfekt aus – sk1ey
Großartig! Sie können es auschecken, indem Sie bereits einen Snapshot Build verwenden :) –