import javafx.scene.paint.Color import tornadofx.* class MyApp: App(MyView::class) class MyView : View("My View") { val controller: CustomerController by inject() override val root = borderpane { center = tableview { items = controller.customers isEditable = true column("ID",Customer::idProperty) column("LAST NAME", Customer::firstNameProperty).apply { cellDecorator { val item = rowItem textFill = if (item.model.lastName.isDirty) Color.RED else Color.BLACK } useTextField() } column("FIRST NAME", Customer::lastNameProperty).apply { cellDecorator { val item = rowItem textFill = if (item.model.firstName.isDirty) Color.RED else Color.BLACK } useTextField() } column("IS DIRTY", Customer::isDirtyProperty) } } } class CustomerController : Controller() { val customers = listOf( Customer(1, "Marley", "John"), Customer(2, "Schmidt", "Ally"), Customer(3, "Johnson", "Eric") ).observable() } class Customer(id: Int, lastName: String, firstName: String) { var lastName by property(lastName) fun lastNameProperty() = getProperty(Customer::lastName) var firstName by property(firstName) fun firstNameProperty() = getProperty(Customer::firstName) var id by property(id) fun idProperty() = getProperty(Customer::id) val model = CustomerModel().apply { this.item = this@Customer } val isDirtyProperty = model.dirtyStateProperty() } class CustomerModel: ItemViewModel() { val lastName = bind { item?.lastNameProperty() } val firstName = bind { item?.firstNameProperty() } val id = bind { item?.idProperty() } }