import javafx.animation.AnimationTimer import javafx.collections.FXCollections import javafx.scene.paint.Color import javafx.scene.shape.Rectangle import javafx.util.Duration import tornadofx.* class LearnApp : App(LearnV::class) class LearnV : View("learn 分錢問題") { // 每一個矩形寬度 val w = 10.0 // 100個矩形容器 val rec = FXCollections.observableArrayList<Rectangle>() val b = (0..99) val money0 = 50 // 100我的,每人money0元 val money = b.map { money0 }.toIntArray() // 動畫計時器 val aniTimer = AniTimer(this) // 每次給其餘人10元 val money1 = 5 val result = stringProperty() val max = stringProperty() val h= doubleProperty() override val root = borderpane { top = vbox(5) { label(result) { isWrapText = true } label(max) hbox(5) { button("run").action { // ani() aniTimer.start() } button("stop").action { // ani() aniTimer.stop() } button("transform").action { // ani() rec[1].transform( Duration.seconds(1.0), javafx.geometry.Point2D(1.0, 1.0), 0, javafx.geometry.Point2D(1.0, 2.0), 100 ) rec[2].translateY = 20.0 rec[3].translateX = 5.0 rec[4].translateZ = 20.0 rec[5].height = 60.0 } } } center = group { canvas { this.graphicsContext2D.fill=Color.AZURE this.height = 800.0 this.width = 1000.0 h.bind(heightProperty()) for (i in money.indices) { val r = rectangle(w * i, 200.0, w - 5, money0) { fill = Color.BLUE } rec.add(r) } } } // barchart("Unit Sales Q2 2016", CategoryAxis(), NumberAxis()) { // series("Product X") { // (0..50).forEach { // data("${it}", 10245) // } // } // } // prefWidth = 800.0 // prefHeight = 800.0 } fun paint() { var i = 0 timeline { keyframe(Duration.seconds(0.10)) { money.forEach { val j = b.random() // 保證每人手裏有錢 if (money[i] > 0) { money[i] -= money1 money[j] += money1 keyvalue(rec[i].heightProperty(), money[i]) keyvalue(rec[j].heightProperty(), money[j]) } i++ } // 如要看排序後的結果,取消下面註釋 money.sort() result.value = money.toList().toString() max.value = "最大值:${money.max()}" // println(money.toList()) } } } // 抖動明顯 fun paint1() { var i = 0 timeline { keyframe(Duration.seconds(0.10)) { money.forEach { val j = b.random() money[i] -= money1 money[j] += money1 if (money[i] > 0) { rec[i].y = 500.0 - money[i] keyvalue(rec[i].heightProperty(), money[i]) } else { rec[i].fill = Color.RED rec[i].y = 500.0 keyvalue(rec[i].heightProperty(), -money[i]) } i++ } // 如要看排序後的結果,取消下面註釋 money.sort() result.value = money.toList().toString() max.value = "最大值:${money.max()}" // println(money.toList()) } } } fun paint2() { var i = 0 money.forEach { val j = b.random() money[i] -= money1 money[j] += money1 if (money[i] > 0) { // rec[i].y = h.value/2 - money[i] rec[i].translateY = h.value/2 - money[i] rec[i].height = money[i].toDouble() } else { rec[i].fill = Color.RED // rec[i].y = h.value/2 rec[i].translateY = h.value/2 rec[i].height = -money[i].toDouble() } i++ } // 如要看排序後的結果,取消下面註釋 money.sort() result.value = money.toList().toString() max.value = "最大值:${money.max()}" // println(money.toList()) } // 此方法能夠中止動畫 class AniTimer(val learnV: LearnV) : AnimationTimer() { var lastTime = 0L override fun handle(now: Long) { if ((now - lastTime) > 10000000) { lastTime = now } else { return } // learnV.paint() // learnV.paint1() learnV.paint2() } } // 此方法沒法中止動畫 fun ani() { class AniTimer : AnimationTimer() { var lastTime = 0L override fun handle(now: Long) { if ((now - lastTime) > 10000000) { lastTime = now } else { return } paint() } } AniTimer().start() } }