import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.scene.layout.BorderPane; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; /** * This program shows an animation where 100 semi-transparent disks of * various sizes grow continually, disappearing before they get too big. * When a disk disappears, it is replaced by a new disk at another location. * This program uses class CircleInfo, defined in CircleInfo.java. */ public class GrowingCircleAnimation extends Application { private CircleInfo[] circleData; // holds the data for all 100 circles /** * Draw one frame of the animation. If there is no disk data (which is * true for the first frame), 100 disks with random locations, colors, * and radii are created. In each frame, all the disks grow by * one pixel per frame. Disks sometimes disappear at random, or when * their radius reaches 100. When a disk disappears, a new disk appears * with radius 1 and with a random location and color */ private void drawFrame(GraphicsContext g, int frameNumber, int width, int height) { g.setFill(Color.WHITE); g.fillRect(0,0,width,height); if (circleData == null) { // create the array, if it doesn't exist circleData = new CircleInfo[100]; for (int i = 0; i < circleData.length; i++) { circleData[i] = new CircleInfo( (int)(width*Math.random()), (int)(height*Math.random()), (int)(100*Math.random()) ); } } for (int i = 0; i < circleData.length; i++) { // draw the filled circles circleData[i].radius++; circleData[i].draw(g); if (Math.random() < 0.005 || circleData[i].radius > 100) { // replace circle number i with a new circle circleData[i] = new CircleInfo( (int)(width*Math.random()), (int)(height*Math.random()), 1 ); } } } //------ Implementation details: DO NOT EXPECT TO UNDERSTAND THIS ----- public void start(Stage stage) { int width = 600; int height = 480; Canvas canvas = new Canvas(width,height); drawFrame(canvas.getGraphicsContext2D(), 0, width, height); BorderPane root = new BorderPane(canvas); root.setStyle("-fx-border-width: 4px; -fx-border-color: #444"); Scene scene = new Scene(root); stage.setScene(scene); stage.setTitle("Growing Circles"); stage.show(); stage.setResizable(false); AnimationTimer anim = new AnimationTimer() { private int frameNum; long previousFrameTime; public void handle(long time) { if (time - previousFrameTime > 0.95e9/60) { // The if statement should not be necessary! It's there because of // a bug that has shown up in some versions of Java on some computers. // The if statement throttles the frame rate to 60 per second, in case // JavaFX incorrectly fails to do that itself. frameNum++; drawFrame(canvas.getGraphicsContext2D(), frameNum, width, height); previousFrameTime = time; } } }; anim.start(); } public static void main(String[] args) { launch(); } }