import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.Button;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;

public class CanvasTest extends Application {

    private static final double CANVAS_SIZE = 300;
    private static final double RECT_SIZE = 5;
    private static final double PADDING = 2;
    private static final Color CLEAR_COLOR = Color.DARKBLUE;
    private static final Color COLOR1 = Color.LIME;
    private static final Color COLOR2 = Color.RED;

    private double x = PADDING;
    private double y = PADDING;
    private Color color = COLOR1;

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("Canvas Test");
        VBox root = new VBox(10);

        StackPane canvasPane = new StackPane();

        final Canvas canvas = new Canvas(CANVAS_SIZE, CANVAS_SIZE);
        final GraphicsContext gc = canvas.getGraphicsContext2D();
        canvasPane.getChildren().add(canvas);

        gc.setFill(CLEAR_COLOR);
        gc.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);

        KeyFrame kfStart = new KeyFrame(Duration.ZERO);
        KeyFrame kfEnd = new KeyFrame(Duration.millis(50), e -> {
            gc.setFill(color);
            gc.fillRect(x, y, RECT_SIZE, RECT_SIZE);
            x += 2 * RECT_SIZE;
            if (x >= CANVAS_SIZE - RECT_SIZE - PADDING) {
                x = PADDING;
                y += 2 * RECT_SIZE;
                if (y >= CANVAS_SIZE - RECT_SIZE - PADDING) {
                    y = PADDING;
                    color = (color == COLOR1) ? COLOR2 : COLOR1;
                }
            }
        });
        Timeline tl = new Timeline(kfStart, kfEnd);
        tl.setCycleCount(Timeline.INDEFINITE);

        HBox controlPane = new HBox(10);

        HBox startStopPane = new HBox();

        Button startButton = new Button("Start");
        Button stopButton = new Button("Stop");

        startButton.setOnAction(e -> {
            tl.play();
            stopButton.setDisable(false);
            startButton.setDisable(true);
        });

        stopButton.setOnAction(e -> {
            tl.pause();
            startButton.setDisable(false);
            stopButton.setDisable(true);
        });
        stopButton.setDisable(true);

        startStopPane.getChildren().addAll(startButton, stopButton);

        Button resetButton = new Button("Reset");
        resetButton.setOnAction(e -> {
            x = y = PADDING;
            gc.setFill(CLEAR_COLOR);
            gc.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
        });

        controlPane.getChildren().addAll(startStopPane, resetButton);

        root.getChildren().addAll(controlPane, canvasPane);

        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

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

}
