package journal import javafx.beans.property.SimpleStringProperty import javafx.geometry.Insets import javafx.geometry.Pos import javafx.scene.control.Alert import javafx.scene.layout.Priority import tornadofx.* class SalesRecord(var id : Int, office : String, year : String, quarter : String, totalSales : String) { val officeProperty = SimpleStringProperty(office) val yearProperty = SimpleStringProperty(year) val quarterProperty = SimpleStringProperty(quarter) val totalSalesProperty = SimpleStringProperty(totalSales) val objectId = nextObjectId() // always increasing companion object { private var idgen = 1 // faux static class member fun nextObjectId() = idgen++ } override fun toString(): String { return "id=${id} objectId=${objectId} - ${officeProperty.value} ${yearProperty.value}/${quarterProperty .value} " + "sales=${totalSalesProperty.value}" } } enum class ActionType { ADD, UPDATE, DELETE } class Action(val actionType : ActionType, val data : SalesRecord) class SaveCompletedEvent : FXEvent() class JournalController : Controller() { val data = mutableListOf( SalesRecord(990, "Home", "2018", "1", "100000"), SalesRecord(991, "NY", "2018", "1", "200000"), SalesRecord(992, "Home", "2018", "2", "125000"), SalesRecord(993, "NY", "2018", "2", "190000") ).observable() val pendingActions = mutableListOf() val consoleLog = SimpleStringProperty("") fun save() { pendingActions.forEach { when(it.actionType) { ActionType.ADD -> { consoleLog += "Calling create service on ${it.data}\n" if( it.data.id == -1 ) { it.data.id = nextId() // as though returned by a service call } } ActionType.UPDATE -> consoleLog += "Calling update service on ${it.data}\n" ActionType.DELETE -> consoleLog += "Calling delete service on ${it.data}\n" } } pendingActions.clear() fire(SaveCompletedEvent()) } fun newItem() { val newRecord = SalesRecord(-1, "Home", "2018", "3", "0.0") add(newRecord) } fun add(record : SalesRecord) { pendingActions.add( Action(ActionType.ADD, record) ) data.add( record ) } fun delete(record : SalesRecord) { pendingActions.add(Action(ActionType.DELETE, record)) data.remove(record) } fun update(record : SalesRecord) { pendingActions.add(Action(ActionType.UPDATE, record)) } // used to generate fake ids from create call companion object { private var idgen = 8000 fun nextId() = idgen++ } } class JournalView : View("Journal App") { val c : JournalController by inject() override val root = vbox { button("+") { action { c.newItem() } } tableview(c.data) { isEditable = true column("Office", SalesRecord::officeProperty).makeEditable().setOnEditCommit { c.update(it.rowValue) } column("Year", SalesRecord::yearProperty).makeEditable().setOnEditCommit { c.update(it.rowValue) } column("Quarter", SalesRecord::quarterProperty).makeEditable().setOnEditCommit { c.update(it.rowValue) } column("TotalSalesProperty", SalesRecord::totalSalesProperty).makeEditable().setOnEditCommit { c.update(it.rowValue) } contextmenu { item("Delete") { action { if (selectedItem != null) { c.delete(selectedItem!!) } } } } vgrow = Priority.ALWAYS } titledpane("Console") { textarea(c.consoleLog) } separator() hbox { button("Save") { action{ c.save() } } alignment = Pos.TOP_RIGHT padding = Insets(4.0) } padding = Insets(4.0) spacing = 4.0 prefWidth = 800.0 prefHeight = 600.0 } init { subscribe { alert(Alert.AlertType.INFORMATION, "Save Saved Successfully") } } } class JournalingApp : App(JournalView::class) fun main(args: Array) { launch(args) }