0

I want to add a sequence of points into a canvas. But the outcome is showing all points at the same time. Here is my code:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.Random;

public class BasicOpsTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Drawing Operations Test");
        Group root = new Group();
        Canvas canvas = new Canvas(300, 250);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
        drawShapes(gc);
    }

    private void drawShapes(GraphicsContext gc) {
        gc.setFill(Color.GREEN);
        gc.setStroke(Color.BLUE);
        Random rand = new Random();
        for (int i = 0; i < 200; i++) {
            gc.fillOval(rand.nextDouble() * 300, rand.nextDouble() * 250, 2, 2);
            try {
                Thread.sleep(10);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

I want to see the outcome adding each point successively. How can I do?

/////////// My solution using AnimationTimer is:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.animation.AnimationTimer;

import java.util.Random;

public class BasicOpsTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Drawing Operations Test");
        Group root = new Group();
        Canvas canvas = new Canvas(300, 250);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
        drawShapes(gc);
    }

    private void drawShapes(GraphicsContext gc) {
        Random rand = new Random();
        gc.setFill(Color.GREEN);
        AnimationTimer at = new AnimationTimer() {
            public void handle(long now) {
                gc.fillOval(rand.nextDouble() * 300, rand.nextDouble() * 250, 2, 2);
            }
        };
        at.start();
    }
}

That resolve my problem!

蘇哲聖
  • 735
  • 9
  • 17
  • 1
    You might be able to use a [`Timeline`](https://docs.oracle.com/javase/10/docs/api/javafx/animation/Timeline.html) for this. By the way, `Thread.sleep` won't work since you will be sleeping the rendering thread. – Slaw Sep 05 '18 at 02:48
  • Practically, I would like to add a infinite sequence of points. Hence it seems impossible to use `Timeline` to add infinite `KeyFrame`s. – 蘇哲聖 Sep 05 '18 at 03:07
  • 1
    In that case you can probably implement [`AnimationTimer`](https://docs.oracle.com/javase/10/docs/api/javafx/animation/AnimationTimer.html) to fit your needs. – Slaw Sep 05 '18 at 03:38
  • `AnimationTimer` really works. Thank you. – 蘇哲聖 Sep 05 '18 at 04:38
  • 2
    It's possible to use a `Timeline` for this too. Just move the body of the loop minus the `Thread.sleep` to a event handler of a `KeyFrame` that triggers every 10 ms and set the cycle count to the appropriate value (200 or `Animation.INDEFINITE` for unrestricted repetition). – fabian Sep 05 '18 at 08:31

0 Answers0