使用 tornadofx 编辑详细信息的 TableView 和 Fragment
TableView and Fragment to edit Details with tornadofx
我的模型使用 kotlinx.serialization。
我希望它们的想法不依赖于 JavaFX,因此它们不会公开属性。
给定一个模型,我想要一个表视图来快速表示实例列表,另外还需要一个更详细的片段作为编辑器。
考虑以下模型:
@Serializable
data class Person(
var name: String,
var firstname: String,
var complex: Stuff)
包含表视图的视图包含
private val personlist = mutableListOf<Person>().observable()
带有一个表视图,当按下 Enter 时,它会为选定的行打开一个 PersonEditor
的实例:
tableview(personlist) {
column("name", Person::name)
column("first name", Person::firstname)
setOnKeyPressed { ev ->
selectedItem?.apply {
when (ev.code) {
KeyCode.ENTER -> PersonEditor(this).openModal()
}
}
}
}
我关注了this gitbook section(但不希望模型视图在选择表视图中的另一行时反弹)
编辑器看起来像这样:
class PersonEditor(person: Person) : ItemFragment<Person>() {
val model: Model = Model()
override val root = form {
fieldset("Personal information") {
field("Name") {
textfield(model.name)
}
field("Vorname") {
textfield(model.firstname)
}
}
fieldset("complex stuff") {
//... more complex stuff here
}
fieldset {
button("Save") {
enableWhen(model.dirty)
action { model.commit() }
}
button("Reset") { action { model.rollback() } }
}
}
class Model : ItemViewModel<Person>() {
val name = bind(Person::name)
val firstname = bind(Person::firstname)
//... complex stuff
}
init {
itemProperty.value = mieter
model.bindTo(this)
}
}
当我在详细视图中保存编辑的值时,表视图没有更新。
解决这个问题的最佳实践是什么?
我也不确定,如果我正在做的事情可以被认为是很好的练习,所以我也很乐意就此提出一些建议。
JavaFX 应用程序中的最佳实践是使用可观察的属性。不这样做是一场艰苦的战斗。您可以保留您的精益域对象,但添加具有可观察属性的 JavaFX/TornadoFX 特定版本。此对象可以知道如何复制数据 to/from 您的 "lean" 域对象。
使用这种方法,尤其是与 ItemViewModel 包装器结合使用,将确保您的数据始终得到更新。
您发布的setOnKeyPressed
代码可以更改为:
setOnUserSelect {
PersonEditor(it).openModal()
}
但请注意,您不应该直接实例化视图和片段,因为这样做会跳过 TornadoFX 生命周期中的某些步骤。相反,您应该将 person 作为参数传递,或者创建一个新范围并在该范围内打开编辑器之前将 PersonModel 注入该范围:
setOnUserSelect {
find<PersonEditor>(Scope(PersonEditor(it)))
}
我的模型使用 kotlinx.serialization。 我希望它们的想法不依赖于 JavaFX,因此它们不会公开属性。
给定一个模型,我想要一个表视图来快速表示实例列表,另外还需要一个更详细的片段作为编辑器。
考虑以下模型:
@Serializable
data class Person(
var name: String,
var firstname: String,
var complex: Stuff)
包含表视图的视图包含
private val personlist = mutableListOf<Person>().observable()
带有一个表视图,当按下 Enter 时,它会为选定的行打开一个 PersonEditor
的实例:
tableview(personlist) {
column("name", Person::name)
column("first name", Person::firstname)
setOnKeyPressed { ev ->
selectedItem?.apply {
when (ev.code) {
KeyCode.ENTER -> PersonEditor(this).openModal()
}
}
}
}
我关注了this gitbook section(但不希望模型视图在选择表视图中的另一行时反弹) 编辑器看起来像这样:
class PersonEditor(person: Person) : ItemFragment<Person>() {
val model: Model = Model()
override val root = form {
fieldset("Personal information") {
field("Name") {
textfield(model.name)
}
field("Vorname") {
textfield(model.firstname)
}
}
fieldset("complex stuff") {
//... more complex stuff here
}
fieldset {
button("Save") {
enableWhen(model.dirty)
action { model.commit() }
}
button("Reset") { action { model.rollback() } }
}
}
class Model : ItemViewModel<Person>() {
val name = bind(Person::name)
val firstname = bind(Person::firstname)
//... complex stuff
}
init {
itemProperty.value = mieter
model.bindTo(this)
}
}
当我在详细视图中保存编辑的值时,表视图没有更新。 解决这个问题的最佳实践是什么?
我也不确定,如果我正在做的事情可以被认为是很好的练习,所以我也很乐意就此提出一些建议。
JavaFX 应用程序中的最佳实践是使用可观察的属性。不这样做是一场艰苦的战斗。您可以保留您的精益域对象,但添加具有可观察属性的 JavaFX/TornadoFX 特定版本。此对象可以知道如何复制数据 to/from 您的 "lean" 域对象。
使用这种方法,尤其是与 ItemViewModel 包装器结合使用,将确保您的数据始终得到更新。
您发布的setOnKeyPressed
代码可以更改为:
setOnUserSelect {
PersonEditor(it).openModal()
}
但请注意,您不应该直接实例化视图和片段,因为这样做会跳过 TornadoFX 生命周期中的某些步骤。相反,您应该将 person 作为参数传递,或者创建一个新范围并在该范围内打开编辑器之前将 PersonModel 注入该范围:
setOnUserSelect {
find<PersonEditor>(Scope(PersonEditor(it)))
}