import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class Guruguru extends Application {
    private int r = 50, x = 110, y = 70;
    private double theta = 0; // 角度
    private Canvas canvas;
    private volatile Thread thread;

    public void start(Stage stage) {
        stage.setTitle("ぐるぐる");

        canvas = new Canvas(200, 180);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        paint(gc);

        Button lBtn = new Button("start");
        Button rBtn = new Button("stop");

        lBtn.setOnAction(e -> startThread());
        rBtn.setOnAction(e -> stopThread());

        HBox top = new HBox();
        top.setAlignment(Pos.BASELINE_CENTER);
        top.getChildren().addAll(lBtn, rBtn);
        VBox root = new VBox();
        root.setAlignment(Pos.CENTER);
        root.getChildren().addAll(top, canvas);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();

        startThread();
    }

    private void paint(GraphicsContext gc) {
        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        gc.fillText("HELLO WORLD!", x, y);
    }

    private void startThread() {
        if (thread == null) {
            Task<Void> task = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    Thread thisThread = Thread.currentThread();
                    for (; thread == thisThread; theta += 0.02) {
                        x = 60 + (int)(r * Math.cos(theta)); y = 100 - (int)(r * Math.sin(theta));
                        Platform.runLater(() -> paint(canvas.getGraphicsContext2D()));
                        try {
                            Thread.sleep(30); // 30 ミリ秒お休み
                        } catch (InterruptedException e) {}
                    }
                    return null;
                }
            };
            thread = new Thread(task);
            thread.setDaemon(true);
            thread.start();
        }
    }

    private void stopThread() {
        thread = null;
    }

    public static void main(String... args) {
        launch(args);
    }
}
