Tornadofx tableview 使用 comboBox 并在按钮上添加 FXEvent
Tornadofx tableview using comboBox & adding FXEvent on buttons
我需要以下基本问题的帮助:
要求:
我有一个可以编辑(内联)的表格视图,也可以删除行,如果需要,还可以通过单击按钮进行一些复杂的操作。
我的看法,以下是3个小问题:
- 我创建了一个 isEditable = true 的表视图,并将列名设置为可编辑。但是当我编辑时,它不会绑定到模型。 (一定漏掉了一个很简单的东西)
- 编辑时,组合框显示选项,但在选择值时抛出异常。
java.lang.ClassCastException:
javafx.beans.property.SimpleStringProperty cannot be cast to
javafx.beans.property.ObjectProperty
然后,我添加了一个删除按钮,当我取消注释 tableView.items.removeAt(index)
时它可以正常工作
但是因为我想要一些额外的功能,所以我决定使用 FXEvent fire。但是我应该如何在这里使用它。
class MyView : View() {
val warriorModel : WarriorModel by inject()
val persons = FXCollections.observableArrayList<Warrior>(
Warrior(1,"Tyrion Lannister", "M"),
Warrior(2,"Ned Stark", "M"),
Warrior(3,"Daenerys Targaryen", "F"),
Warrior(4,"Arya Stark", "F")
)
override val root = vbox {
tableview(persons) {
isEditable = true
column("ID", Warrior::idProperty)
column("Name", Warrior::nameProperty).makeEditable()
column("Gender", Warrior::genderProperty).useComboBox(FXCollections.observableArrayList("M", "F"))
column("Action", Warrior::dummyProperty).setCellFactory { DeleteButton<Warrior>() }
bindSelected(warriorModel)
subscribe<DeleteEvent> { event ->
items.removeAt(event.index)
}
}
}
}
class DeleteButton<Warrior>() : TableCell<Warrior, String?>() {
internal val btn = Button("Delete")
override fun updateItem(item: String?, empty: Boolean) {
super.updateItem(item, empty)
if (empty) {
graphic = null
text = null
} else {
btn.setOnAction { event: ActionEvent ->
//tableView.items.removeAt(index)
fire(DeleteEvent(index))
}
graphic = btn
text = null
}
}
}
class Warrior(id: Int, name: String, gender: String) {
val idProperty = SimpleIntegerProperty(id)
var id by idProperty
val nameProperty = SimpleStringProperty(name)
var name by nameProperty
val genderProperty = SimpleStringProperty(gender)
var gender by genderProperty
val dummyProperty = SimpleStringProperty("")
}
class WarriorModel : ItemViewModel<Warrior>() {
val id = bind { item?.idProperty }
val name = bind { item?.nameProperty }
val gender = bind { item?.genderProperty }
}
class DeleteEvent(val index: Int) : FXEvent()
要从 Component
外部访问 EventBus,请使用 FX.eventbus
变量,并在该变量上触发事件:
FX.eventbus.fire(DeleteEvent(index))
更改组合框中的值时出现错误的原因是框架中的错误。我刚刚提交了一个修复程序,但在 1.5.10 版本发布之前,您可以通过将此扩展功能添加到您的应用程序来解决此问题:
fun <S, T> TableColumn<S, T?>.useComboBoxWorking(items: ObservableList<T>, afterCommit: ((TableColumn.CellEditEvent<S, T?>) -> Unit)? = null): TableColumn<S, T?> {
cellFactory = ComboBoxTableCell.forTableColumn(items)
setOnEditCommit {
val property = it.tableColumn.getCellObservableValue(it.rowValue) as Property<T?>
property.value = it.newValue
afterCommit?.invoke(it)
}
return this
}
现在只需调用 .useComboBoxWorking()
,你应该是金子:)
如果您不想使用解决方法,您可以暂时将 Warrior
的 genderProperty
更改为 SimpleObjectProperty<String>
类型,而不是 SimpleStringProperty
作为备选方案。
我需要以下基本问题的帮助:
要求:
我有一个可以编辑(内联)的表格视图,也可以删除行,如果需要,还可以通过单击按钮进行一些复杂的操作。
我的看法,以下是3个小问题:
- 我创建了一个 isEditable = true 的表视图,并将列名设置为可编辑。但是当我编辑时,它不会绑定到模型。 (一定漏掉了一个很简单的东西)
- 编辑时,组合框显示选项,但在选择值时抛出异常。
java.lang.ClassCastException: javafx.beans.property.SimpleStringProperty cannot be cast to javafx.beans.property.ObjectProperty
然后,我添加了一个删除按钮,当我取消注释 tableView.items.removeAt(index)
时它可以正常工作
但是因为我想要一些额外的功能,所以我决定使用 FXEvent fire。但是我应该如何在这里使用它。
class MyView : View() {
val warriorModel : WarriorModel by inject()
val persons = FXCollections.observableArrayList<Warrior>(
Warrior(1,"Tyrion Lannister", "M"),
Warrior(2,"Ned Stark", "M"),
Warrior(3,"Daenerys Targaryen", "F"),
Warrior(4,"Arya Stark", "F")
)
override val root = vbox {
tableview(persons) {
isEditable = true
column("ID", Warrior::idProperty)
column("Name", Warrior::nameProperty).makeEditable()
column("Gender", Warrior::genderProperty).useComboBox(FXCollections.observableArrayList("M", "F"))
column("Action", Warrior::dummyProperty).setCellFactory { DeleteButton<Warrior>() }
bindSelected(warriorModel)
subscribe<DeleteEvent> { event ->
items.removeAt(event.index)
}
}
}
}
class DeleteButton<Warrior>() : TableCell<Warrior, String?>() {
internal val btn = Button("Delete")
override fun updateItem(item: String?, empty: Boolean) {
super.updateItem(item, empty)
if (empty) {
graphic = null
text = null
} else {
btn.setOnAction { event: ActionEvent ->
//tableView.items.removeAt(index)
fire(DeleteEvent(index))
}
graphic = btn
text = null
}
}
}
class Warrior(id: Int, name: String, gender: String) {
val idProperty = SimpleIntegerProperty(id)
var id by idProperty
val nameProperty = SimpleStringProperty(name)
var name by nameProperty
val genderProperty = SimpleStringProperty(gender)
var gender by genderProperty
val dummyProperty = SimpleStringProperty("")
}
class WarriorModel : ItemViewModel<Warrior>() {
val id = bind { item?.idProperty }
val name = bind { item?.nameProperty }
val gender = bind { item?.genderProperty }
}
class DeleteEvent(val index: Int) : FXEvent()
要从 Component
外部访问 EventBus,请使用 FX.eventbus
变量,并在该变量上触发事件:
FX.eventbus.fire(DeleteEvent(index))
更改组合框中的值时出现错误的原因是框架中的错误。我刚刚提交了一个修复程序,但在 1.5.10 版本发布之前,您可以通过将此扩展功能添加到您的应用程序来解决此问题:
fun <S, T> TableColumn<S, T?>.useComboBoxWorking(items: ObservableList<T>, afterCommit: ((TableColumn.CellEditEvent<S, T?>) -> Unit)? = null): TableColumn<S, T?> {
cellFactory = ComboBoxTableCell.forTableColumn(items)
setOnEditCommit {
val property = it.tableColumn.getCellObservableValue(it.rowValue) as Property<T?>
property.value = it.newValue
afterCommit?.invoke(it)
}
return this
}
现在只需调用 .useComboBoxWorking()
,你应该是金子:)
如果您不想使用解决方法,您可以暂时将 Warrior
的 genderProperty
更改为 SimpleObjectProperty<String>
类型,而不是 SimpleStringProperty
作为备选方案。