Tornadofx tableview使用comboBox&在按钮上添加FXEvent

时间:2017-01-02 19:34:43

标签: javafx kotlin tornadofx

我需要帮助解决以下基本问题:

要求:
我有一个可以编辑的表视图(内联),也可以删除行,如果需要,也可以点击一个按钮进行一些复杂的操作。

我的看法,下面是3个小问题:

  1. 我使用isEditable = true创建了一个tableview,并使列名可编辑。但是当我编辑时,它并没有绑定到模型。 (必须遗漏一件非常简单的事情)
  2. 编辑时,comboBox会显示选项但是选择一个值会引发异常。
  3.   

    java.lang.ClassCastException:   javafx.beans.property.SimpleStringProperty无法强制转换为   javafx.beans.property.ObjectProperty

    然后,我添加了一个删除按钮,当我取消注释tableView.items.removeAt(index)时工作正常 但由于我想要一些额外的功能,我决定采用FXEvent火。但是我应该如何在这里使用它。

    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()
    

1 个答案:

答案 0 :(得分:3)

要从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(),你应该是金色的:)

如果您不想使用变通方法,可以暂时将genderProperty的{​​{1}}更改为Warrior,而不是SimpleObjectProperty<String>替代品。