如下代碼經過Timer實現動畫,沒法暫停、繼續java
import javafx.application.Application import javafx.application.Platform import javafx.geometry.Pos import javafx.scene.canvas.GraphicsContext import javafx.scene.paint.Color import tornadofx.* import java.util.* fun main(args: Array<String>) { Application.launch(TestApp::class.java, *args) } class TestApp:App(TestView::class) class TestView : View("逐個顯示圖形") { val timer = Timer() val isRun= booleanProperty() val pNums= intProperty() lateinit var context: GraphicsContext override val root = borderpane { top = hbox(10) { style{ alignment= Pos.CENTER } button("start") { action { if(isRun.value){ timer.cancel() this.text="Start" isRun.value=false }else{ timer.schedule(task, 0, 100) this.text="Pause" isRun.value=true } } } label(pNums.stringBinding{"當前點數:$it"}) } center = canvas(800.0, 600.0) { style{ alignment= Pos.CENTER } context=this.graphicsContext2D paddingAll=30 } primaryStage.setOnCloseRequest { timer.cancel() } } val task = object : TimerTask() { var renderedList: MutableList<Point> = LinkedList<Point>() var syncLock = Any() override fun run() { Platform.runLater { val random = Random() val x = 100 + random.nextDouble() * 500 val y = 100 + random.nextDouble() * 500 val p = Point(x, y,Color.RED) // 鎖住,防止其餘線程修改 synchronized(syncLock) { // 添加歷史記錄 renderedList.add(p) // 清屏 context.fill = Color.WHITE context.clearRect(0.0, 0.0, 800.0, 600.0) context.fill = p.color // 渲染點 for (point in renderedList) { context.fillOval(point.x, point.y, 20.0, 20.0) } pNums.value+=1 // 控制點的數量 if (renderedList.size > 120) { renderedList.clear() pNums.value=0 } } } } } } class Point(val x: Double, val y: Double, val color:Color)
如下代碼經過AnimationTimer實現動畫,能夠暫停、繼續canvas
import javafx.animation.AnimationTimer import javafx.application.Application import javafx.application.Platform import javafx.geometry.Pos import javafx.scene.canvas.GraphicsContext import javafx.scene.paint.Color import tornadofx.* import java.util.* fun main(args: Array<String>) { Application.launch(TestApp::class.java, *args) } class TestApp:App(TestView::class) class TestView : View("逐個顯示圖形") { val timer = Timer() val isRun= booleanProperty() val pNums= intProperty() val aniMate=AniTimer() lateinit var context: GraphicsContext override val root = borderpane { top = hbox(10) { style{ alignment= Pos.CENTER } button("start") { action { if(isRun.value){ aniMate.stop() this.text="Start" isRun.value=false }else{ aniMate.start() this.text="Pause" isRun.value=true } } } label(pNums.stringBinding{"當前點數:$it"}) } center = canvas(800.0, 600.0) { style{ alignment= Pos.CENTER } context=this.graphicsContext2D paddingAll=30 } primaryStage.setOnCloseRequest { timer.cancel() } } inner class AniTimer : AnimationTimer() { var lastTime = 0L var renderedList: MutableList<Point> = LinkedList<Point>() var syncLock = Any() override fun handle(now: Long) { if ((now - lastTime) > 10000000) { lastTime = now } else { return } Platform.runLater { val random = Random() val x = 100 + random.nextDouble() * 500 val y = 100 + random.nextDouble() * 500 val p = Point(x, y,Color.RED) // 鎖住,防止其餘線程修改 synchronized(syncLock) { // 添加歷史記錄 renderedList.add(p) // 清屏 context.fill = Color.WHITE context.clearRect(0.0, 0.0, 800.0, 600.0) context.fill = p.color // 渲染點 for (point in renderedList) { context.fillOval(point.x, point.y, 20.0, 20.0) } pNums.value+=1 // 控制點的數量 if (renderedList.size > 120) { renderedList.clear() pNums.value=0 } } } } } } class Point(val x: Double, val y: Double, val color:Color)