This blog entry just shows a screenshot and the code for a little JavaFX AnimationTimer test I wrote.
AnimationTimer is a JavaFX class which comes in handy if you are in need of a callback hook which should be called on every frame. With this class it is possible to implement simple animations for example, but it could be used for various other things as well. The example code below shows how to make hundreds of circles wiggle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.ladstatt.fx.animations | |
import java.net.URL | |
import java.util.ResourceBundle | |
import javafx.animation.AnimationTimer | |
import javafx.application.Application | |
import javafx.fxml._ | |
import javafx.scene.layout.AnchorPane | |
import javafx.scene.paint.Color | |
import javafx.scene.shape.Circle | |
import javafx.scene.{Parent, Scene} | |
import javafx.stage.Stage | |
import scala.collection.immutable.IndexedSeq | |
import scala.util.Random | |
import scala.util.control.NonFatal | |
/** | |
* AnimationTimer Example | |
* | |
* Shows an example how to use the JavaFX AnimationTimer class | |
*/ | |
object FxAnimations { | |
def main(args: Array[String]) { | |
Application.launch(classOf[FxAnimationsApp], args: _*) | |
} | |
} | |
class FxAnimationsApp extends javafx.application.Application { | |
val loader = new FXMLLoader(getClass.getResource("FxAnimations.fxml")) | |
override def start(stage: Stage): Unit = | |
try { | |
stage.setTitle("FxAnimations App") | |
loader.load[Parent]() | |
stage.setScene(new Scene(loader.getRoot[Parent])) | |
stage.show() | |
} catch { | |
case NonFatal(e) => e.printStackTrace() | |
} | |
} | |
case class CircleAnimation(circles : Seq[Circle]) extends AnimationTimer { | |
// every tick this method is called - you are free to do whatever you want | |
// in this method. maybe animate something, maybe something else ... | |
override def handle(now: Long): Unit = { | |
circles.foreach { | |
case c => | |
c.setCenterX(c.getCenterX + Random.nextDouble * 4 - 2) | |
c.setCenterY(c.getCenterY + Random.nextDouble * 4 - 2) | |
} | |
} | |
} | |
class FxAnimationsController extends Initializable { | |
@FXML var canvasAnchorPane: AnchorPane = _ | |
def randColor(): Color = Color.color(Random.nextDouble, Random.nextDouble(), Random.nextDouble) | |
override def initialize(location: URL, resources: ResourceBundle): Unit = { | |
val width = canvasAnchorPane.getMinWidth | |
val height = canvasAnchorPane.getMinHeight | |
val circles: IndexedSeq[Circle] = | |
for (i <- 1 to 2000) yield { | |
mkCircle(width.toInt, height.toInt, Random.nextInt(20) +1 ) | |
} | |
canvasAnchorPane.getChildren.addAll(circles: _*) | |
CircleAnimation(circles).start() | |
} | |
def mkCircle(width: Int, height: Int, maxRadius: Int): Circle = { | |
val c = new Circle(Random.nextInt(width), Random.nextInt(height), Random.nextInt(maxRadius)) | |
c.setFill(randColor()) | |
c | |
} | |
} |
A self contained project is available here.
No comments:
Post a Comment