import javafx.collections.FXCollections import javafx.scene.input.* import javafx.scene.paint.Color import javafx.scene.shape.Circle import tornadofx.* class LearnApp : App(LearnV::class) class LearnV : View("learn") { val dots = mutableListOf<Circle>() val count = stringProperty() override val root = borderpane { top = toolbar { Buttons.values().forEach { ss -> button(ss.toString().replace("_", " ")) { action { ss.run() } useMaxWidth = true } } } center = pane { Dot.all.onChange { children.removeAll(dots) dots.clear() it.list.forEach { Circle(it.x, it.y, 5.0).apply { fill = Color.RED children += this dots += this } } count.value = dots.size.toString() } addEventHandler(MouseEvent.MOUSE_CLICKED) { Dot.create(it.x, it.y) count.value = dots.size.toString() } } bottom { form { fieldset { field("Dots created:") { label(count) } } } } prefWidth = 200.0 prefHeight = 200.0 } } enum class Buttons { Clear { override fun run() { Dot.all.clear() } }, Add { override fun run() { val dot = Dot.create((1..200).random().toDouble(), (1..200).random().toDouble()) } }; abstract fun run() } class Dot(val id: Int, val x: Double, val y: Double) { companion object { val all = FXCollections.observableArrayList<Dot>() fun create(x: Double, y: Double): Dot { val nextId = (all.asSequence().map { it.id }.max() ?: -1) + 1 return Dot(nextId, x, y).also { all += it } } } }