1. 程式人生 > >tornadofx使用barchart、AnimationTimer、timeline動畫演示選擇排序,第1版

tornadofx使用barchart、AnimationTimer、timeline動畫演示選擇排序,第1版

檢視演示:https://www.bilibili.com/video/av59653274/


import javafx.animation.AnimationTimer
import  javafx.collections.FXCollections
import javafx.scene.chart.CategoryAxis
import javafx.scene.chart.NumberAxis
import javafx.scene.chart.XYChart
import javafx.util.Duration
import  tornadofx.*
import kotlin.collections.ArrayList

class LearnApp : App(LearnV::class)

class LearnV : View("learn 選擇排序") {
    //    動畫計時器
    val aniTimer = AniTimer(this)
    //    每次給其他人10元
    val result = stringProperty()
    lateinit var data1: XYChart.Data<String, Number>
    val datas = FXCollections.observableArrayList<XYChart.Data<String, Number>>()
    val N = 100
    val randomBound = 200
    val data0 = SelectionSortData(N, randomBound)

    override val root = borderpane {
        top = vbox(5) {
            result.value = data0.numbers.toString()

            label(result) {
                isWrapText = true
            }
            hbox(5) {
                button("run").action {
                    //                ani()
                    aniTimer.start()
                }
                button("stop").action {
                    //                ani()
                    aniTimer.stop()
                }
            }
        }
        center = group {
            barchart("選擇排序", CategoryAxis(), NumberAxis(0.0, randomBound.toDouble(), 10.0)) {
                series("Product X") {
                    (1..N).forEach {
                        data1 = data("${it}", data0.numbers[it - 1])
                        datas.add(data1)
                    }
                    barGap = 0.01

                }
                categoryGap = 5.0
                prefWidth = 1000.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(datas[i].YValueProperty(), data0.numbers[i])
                    result.value = 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
    }
}