tornadofx使用rectangle、AnimationTimer、timeline動畫演示選擇排序,第2版
阿新 • • 發佈:2019-08-24
import javafx.animation.AnimationTimer
import javafx.collections.FXCollections
import javafx.scene.paint.Color
import javafx.scene.shape.Rectangle
import javafx.util.Duration
import tornadofx.*
import kotlin.collections.ArrayList
class LearnApp : App(LearnV::class)
class LearnV : View("learn 選擇排序") {
// 每個矩形寬度
val w = 6.0
// 100個矩形容器
val rec = FXCollections.observableArrayList<Rectangle>()
// 動畫計時器
val aniTimer = AniTimer(this)
val result = stringProperty()
val N = 100
val randomBound = 200
val data0 = SelectionSortData(N, randomBound)
override val root = borderpane {
top = vbox(5) {
result.value = "result:${data0.numbers.toString()}"
label(result) {
isWrapText = true
}
hbox(5) {
button("run").action {
// ani()
aniTimer.start()
}
button("stop").action {
// ani()
aniTimer.stop()
}
}
}
center = group {
(1..N).forEach{
val r = rectangle(w * it, 200.0, w - 2, data0.numbers[it - 1]) {
fill = Color.BLUE
}
rec.add(r)
}
}
center.rotate=180.0
prefHeight = 800.0
prefWidth = 1000.0
}
fun paint() {
timeline {
keyframe(Duration.seconds(0.0010)) {
for (i in data0.numbers.indices) {
var minIndex = i
var j = i + 1
if (j < data0.N()) {
(j..data0.N()).map {
if (data0.get(j) < data0.get(minIndex)) {
minIndex = j
}
}
}
data0.swap(i, minIndex)
keyvalue(rec[i].heightProperty(), data0.numbers[i])
result.value = "result:${data0.numbers.toString()}"
}
}
}
}
// 此方法可以停止動畫
class AniTimer(val learnV: LearnV) : AnimationTimer() {
var lastTime = 0L
override fun handle(now: Long) {
if ((now - lastTime) > 10000000) {
lastTime = now
} else {
return
}
learnV.paint()
}
}
}
class SelectionSortData {
val numbers = ArrayList<Int>()
constructor(N: Int, randomBound: Int) {
(1..N).map { numbers.add((1..randomBound).random()) }
}
fun N() = numbers.size
fun get(i: Int) = numbers[i]
fun swap(i: Int, j: Int) {
val t = numbers[i]
numbers[i] = numbers[j]
numbers[j] = t
}
}