package listnavapp import javafx.beans.property.SimpleBooleanProperty import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleStringProperty import javafx.scene.control.TextField import javafx.scene.layout.Priority import javafx.util.Duration import tornadofx.* import java.time.LocalDate class Todo(descr : String = "New Item", completed : Boolean = false, completedBy : LocalDate? = null) { val descrProperty = SimpleStringProperty(descr) val completedProperty = SimpleBooleanProperty(completed) val completedByProperty = SimpleObjectProperty(completedBy) } class TodoItemViewModel : ItemViewModel() { val selectedDescr = bind(Todo::descrProperty) val selectedCompleted = bind(Todo::completedProperty) val selectedCompletedBy = bind(Todo::completedByProperty) init { autocommitProperties.addAll(selectedDescr, selectedCompleted, selectedCompletedBy) } } class ListNavController : Controller() { val data = mutableListOf().observable() fun newItem() { data.add( Todo()) } } class ListDetailsView : View("List Nav - Details") { val mainView : ListNavView by inject() val todoItemViewModel : TodoItemViewModel by inject() var tf : TextField by singleAssign() override val root = vbox { button("<") { action { this@ListDetailsView.replaceWith( mainView, ViewTransition.Slide(Duration.seconds(0.5), tornadofx.ViewTransition.Direction.RIGHT) ) } } form { fieldset { field("Descr") { tf = textfield(todoItemViewModel.selectedDescr) } field("Completed") { checkbox { bind(todoItemViewModel.selectedCompleted) } } field("Completed By") { datepicker(todoItemViewModel.selectedCompletedBy) } } } spacing = 4.0 paddingTop = 4.0 } override fun onDock() = tf.requestFocus() } class TodoListItemFragment : ListCellFragment() { val model = TodoItemViewModel().bindTo(this) override val root = hbox { checkbox(property = model.selectedCompleted) vbox { label(model.selectedDescr) label(model.selectedCompletedBy, converter = javafx.util.converter.LocalDateStringConverter()) } } } class ListNavView : View("List Nav") { val c : ListNavController by inject() val detailsView : ListDetailsView by inject() val todoItemViewModel : TodoItemViewModel by inject() override val root = vbox { button("+") { action { c.newItem() } } listview(c.data) { bindSelected(todoItemViewModel) onDoubleClick { this@ListNavView.replaceWith(detailsView, ViewTransition.Slide(Duration.seconds(0.5))) } cellFragment(TodoListItemFragment::class) vgrow = Priority.ALWAYS } prefHeight = 480.0 prefWidth = 320.0 spacing = 4.0 paddingTop = 4.0 } } class ListNavApp : App(ListNavView::class) fun main(args: Array) { launch(args) }