我对Kotlon,JavaFX和Tornadofx都很陌生。我喜欢到目前为止看到的:) (也是Stackoverflow的新功能,我希望我没有把它拉得太远......
我有一个应用程序来检索远程JSON数据。编辑该数据并将其作为JSON返回给服务器。
可编辑的表格视图显示此数据(包含嵌套属性),侧面的编辑器也用于编辑。
我附上了一个演示此示例的示例应用程序。这对我来说似乎很多余,而且太复杂了。我想这里肯定有问题:)
感谢您提供的任何指针/帮助! :)
(该模型没有将更改写回POJO。我已经修改了SimpleStringProperty的修补版本,但我甚至不确定我使用它的方式是否是最好的方法。)
package com.jadev.office
import javafx.application.Application
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import javafx.geometry.Orientation
import tornadofx.*
// data classes obtained by parsing JSON from remote server, will be send back to the server to update the data
// Address should be used in several other classes
data class Address(var street: String, var city: String, var country: String)
data class Person(var name: String, var address: Address)
// Editable versions to use in table and editor view, this is wrapping the original data
// to avoid duplicating the properties
class EditableAddress(var address: Address) {
var streetProperty = SimpleStringProperty(address, "street", address.street)
var cityProperty = SimpleStringProperty(address, "city", address.city)
var countryProperty = SimpleStringProperty(address, "country", address.country)
}
class EditablePerson(val person: Person) {
val nameProperty = SimpleStringProperty(person, "name", person.name)
val editableAddress = EditableAddress(person.address)
val addressProperty = SimpleObjectProperty(editableAddress)
val streetProperty = addressProperty.select(EditableAddress::streetProperty)
val cityProperty = addressProperty.select(EditableAddress::cityProperty)
val countryProperty = addressProperty.select(EditableAddress::countryProperty)
}
class PersonViewModel : ItemViewModel<EditablePerson>() {
var name = bind(EditablePerson::nameProperty)
var street = bind(EditablePerson::streetProperty)
var city = bind(EditablePerson::cityProperty)
var country = bind(EditablePerson::countryProperty)
}
val persons = mutableListOf(
Person("Adam", Address("Paradise 1", "Eden", "ED")),
Person("Eve", Address("Paradise 1", "Eden", "ED")))
class MainView : View() {
val editablePersons = FXCollections.observableArrayList<EditablePerson>(persons.map { EditablePerson(it) })
val model: PersonViewModel by inject()
override val root = splitpane(Orientation.HORIZONTAL) {
tableview(editablePersons) {
column("Name", EditablePerson::nameProperty)
column("Street", EditablePerson::streetProperty)
column("City", EditablePerson::cityProperty)
column("Country", EditablePerson::countryProperty)
bindSelected(model)
}
form {
fieldset {
label("Name:")
textfield(model.name)
label("Street:")
textfield(model.street)
label("City:")
textfield(model.city)
label("Country:")
textfield(model.country)
}
button("Save") {
action {
save()
}
}
}
}
fun save() {
//for some reason this is updating the table but not the data wrapped by SimpleStringProperty()
model.commit()
println("Updated person: ${model.item.person}")
println("Updated persons: ${persons}")
}
}
class SampleApp : App(MainView::class)
fun main(args: Array<String>) {
Application.launch(SampleApp::class.java, *args)
}
答案 0 :(得分:0)
我确保始终只有一个域对象和该对象的相应ViewModel。我喜欢实现<RichTextBox x:Name="txt1" IsDocumentEnabled="True" HorizontalAlignment="Left" Height="183" Margin="36,10,0,0" VerticalAlignment="Top" Width="508">
<FlowDocument IsEnabled="True">
<Paragraph LineHeight="1">
<Button Content="Button" Height="25" Width="93" Click="Button_Click_1"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
并直接处理序列化/反序列化。我从未见过需要进行优化,因此我不会在不需要的地方使用可观察值,所以我只是坚持这种模式。
确保每个对象都有一个noargs构造函数也是一个好主意,这样它们就可以在不调用专用构造函数的情况下实例化。
你应该避免在你的对象的不同版本之间进行转换,你只会遇到麻烦和细微的错误,如你所见。相反,我直接在TableView中对地址执行对象遍历。它不是最漂亮的代码,但它更透明。
我确实喜欢你在人物视图模型中公开地址字段的想法,以便他们可以与人一起提交。我已经更改了您的申请以反映这些想法。
JsonModel