【问题标题】:Tornadofx tableview using comboBox & adding FXEvent on buttonsTornadofx tableview 使用组合框并在按钮上添加 FXEvent
【发布时间】:2017-01-03 06:03:40
【问题描述】:

我在以下基本问题上需要帮助:

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

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

  1. 我使用 isEditable = true 创建了一个表格视图,并将列名设为可编辑。但是当我编辑时,它不会绑定到模型。 (一定少了一个很简单的东西)
  2. 编辑时,组合框会显示选项,但在选择值时会引发异常。

java.lang.ClassCastException: javafx.beans.property.SimpleStringProperty 不能强制转换为 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()

【问题讨论】:

  • re: #1 - 是什么让它认为它不绑定到模型 - 它对我有用?您是否在表格单元格上按 Enter 键(只是失去焦点不会强制提交)?
  • 哦..我的错...我没有按回车键,我在外面点击,以为它会自动绑定(来自一个角度世界)..但是功能是有道理的。

标签: javafx kotlin tornadofx


【解决方案1】:

要从 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(),您应该是金子了 :)

如果您不想使用该解决方法,您可以暂时将WarriorgenderProperty 更改为SimpleObjectProperty&lt;String&gt; 类型,而不是SimpleStringProperty

【讨论】:

  • 谢谢 :) ... 现在一切正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-19
相关资源
最近更新 更多