簡體   English   中英

Tornadofx tableview使用comboBox並在按鈕上添加FXEvent

[英]Tornadofx tableview using comboBox & adding FXEvent on buttons

我需要以下基本問題的幫助:

需求:
我有一個可以編輯(內聯)的表視圖,行也可以刪除,如果需要,還可以單擊按鈕進行一些復雜的操作。

我的看法,以下是3個小問題:

  1. 我使用isEditable = true創建了一個表視圖,並將列名設置為可編輯。 但是當我編輯時,它不會綁定到模型。 (必須缺少一個非常簡單的東西)
  2. 編輯時,comboBox顯示選項,但是在選擇值時會引發異常。

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

要從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() ,您應該會很.useComboBoxWorking() :)

如果您不想使用解決方法,則可以暫時將WarriorgenderProperty更改為SimpleObjectProperty<String>類型,而不是使用SimpleStringProperty

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM