import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
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;

public class BubbleSort1 extends Application {
    private final Color[] cs = {Color.RED, Color.BLUE};
    private int[] init = {10, 52, 23, 34, 8, 12, 4, 46, 7, 45, 44, 3};
    private int[] args = new int[init.length];
    private final int scale = 10;
    private volatile Thread thread;
    private int i, j;

    private Canvas canvas;

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("CanvasSmpl");

        canvas = new Canvas(320,250);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        paint(gc);

        Group root = new Group();
        root.getChildren().add(canvas);
        stage.setScene(new Scene(root));
        stage.show();

        startThread();
    }

    private void startThread() {
        if (thread == null) {
            Task<Void> task = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    while (true) {
                        for (int k = 0; k < init.length; k++) { args[k] = init[k]; }
                        // バブルソートアルゴリズム
                        for (i = 0; i < args.length - 1; i++) {
                            for (j = args.length - 1; j > i; j--) {
                                if (args[j - 1] > args[j]) { // スワップする。
                                    int tmp = args[j - 1];
                                    args[j - 1] = args[j];
                                    args[j] = tmp;
                                }
                                Platform.runLater(() -> paint(canvas.getGraphicsContext2D()));
                                try { // repaintの後でしばらく止まる
                                    Thread.sleep(500);
                                } catch (InterruptedException e) {}
                            }
                        }
                    }
                }
            };

            thread = new Thread(task);
            thread.setDaemon(true);
            thread.start();
        }
    }

    private void paint(GraphicsContext gc) {
        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        gc.setFill(Color.YELLOW);
        gc.fillOval(5, 30 + j * scale, scale, scale);
        gc.setFill(Color.CYAN);
        gc.fillOval(5, 30 + i * scale, scale, scale);
        int n = args.length;
        for (int i = 0; i < n; i++) {
            gc.setFill(cs[args[i] % 2]);
            gc.fillRect(20, 30 + i * scale, args[i] * scale / 2, scale);
        }
    }

    public static void main(String... args) {
        launch(args);
    }
}
