JavaFX(Java8)備忘録

トリプルスプレッドさせた時のコードを載せておく。

画像：
img/dog.gif [size:640x480]
img/dog.png
img/tarot_XX.jpg(XX=0~21) [size:300x420]

```java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javafx.animation.ParallelTransition;
import javafx.animation.RotateTransition;
import javafx.animation.ScaleTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

public class Main extends Application {
	private double mouseX;
	private double mouseY;
	private double startX;
	private double startY;
	private int nowPlaying;

	private final int stageHeight = 120;
	private final int cardY = 95;

	@Override
	public void start(Stage primaryStage) {
		try {
			BorderPane root = new BorderPane();
			// ==========
			// 0-21 タロット
			// ==========
			for (Tarot t : Tarot.values()) {
				Image i = new Image(t.image());
				ImageView iv = new ImageView(i);
				iv.setFitHeight(stageHeight / 10);
				iv.setPreserveRatio(true);
				iv.setSmooth(true);
				iv.setCache(true);
				iv.setX(80);
				iv.setY(cardY - stageHeight / 20);
				root.getChildren().add(iv);
			}

			// ==========
			// 22 dog
			// ==========
			Image dog = new Image("img/dog.gif");
			ImageView dogView = new ImageView(dog);
			dogView.setY(stageHeight);
			dogView.setFitWidth(200);
			dogView.setPreserveRatio(true);
			dogView.setSmooth(true);
			dogView.setCache(true);
			root.getChildren().add(dogView);

			Scene scene = new Scene(root, 600, stageHeight);
			scene.setFill(Color.TRANSPARENT);
			primaryStage.initStyle(StageStyle.TRANSPARENT);
			primaryStage.setScene(scene);
			primaryStage.getIcons().add(new Image("img/dog.png"));
			primaryStage.setOnCloseRequest(req -> Platform.exit());
			primaryStage.setX(1920);
			primaryStage.setY(1080 - stageHeight);
			primaryStage.show();

			opening(dogView).play();

			root.setOnMousePressed(e -> {
				switch (e.getButton()) {
				case PRIMARY:
					if (nowPlaying == 0) {
						tripleSpread(root.getChildren());
					}
					break;
				case SECONDARY:
					this.mouseX = primaryStage.getX() - e.getScreenX();
					this.mouseY = primaryStage.getY() - e.getScreenY();
					this.startX = e.getScreenX();
					this.startY = e.getScreenY();
					break;
				case MIDDLE:
					removeTarot(root.getChildren());
					exit(dogView).play();
					break;
				default:
				}
			});
			root.setOnMouseDragged(e -> {
				switch (e.getButton()) {
				case SECONDARY:
					primaryStage.setX(e.getScreenX() + this.mouseX);
					primaryStage.setY(e.getScreenY() + this.mouseY);
				default:
				}
			});
			root.setOnMouseReleased(e -> {
				switch (e.getButton()) {
				case SECONDARY:
					if (this.startX == e.getScreenX() && this.startY == e.getScreenY()) {
						removeTarot(root.getChildren());
					}
				default:
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private ParallelTransition opening(ImageView dogView) {
		ScaleTransition size1 = new ScaleTransition(Duration.millis(250));
		size1.setFromX(0.8);
		size1.setToX(0.8);
		TranslateTransition pos1 = new TranslateTransition(Duration.millis(250));
		pos1.setFromY(0);
		pos1.setToY(-stageHeight);
		ScaleTransition size2 = new ScaleTransition(Duration.millis(150));
		size2.setFromX(0.8);
		size2.setToX(1);
		TranslateTransition pos2 = new TranslateTransition(Duration.millis(150));
		pos2.setByY(20);

		ParallelTransition pt2 = new ParallelTransition(dogView, size2, pos2);
		ParallelTransition pt1 = new ParallelTransition(dogView, size1, pos1);
		pt1.setOnFinished(e -> pt2.play());
		return pt1;
	}

	private ParallelTransition exit(ImageView dogView) {
		ScaleTransition size1 = new ScaleTransition(Duration.millis(150));
		size1.setFromX(1);
		size1.setToX(0.8);
		TranslateTransition pos1 = new TranslateTransition(Duration.millis(150));
		pos1.setToY(-stageHeight);
		ScaleTransition size2 = new ScaleTransition(Duration.millis(250));
		size2.setFromX(0.8);
		size2.setToX(0.8);
		TranslateTransition pos2 = new TranslateTransition(Duration.millis(250));
		pos2.setFromY(-stageHeight);
		pos2.setToY(0);

		ParallelTransition pt2 = new ParallelTransition(dogView, size2, pos2);
		ParallelTransition pt1 = new ParallelTransition(dogView, size1, pos1);
		pt1.setOnFinished(e -> pt2.play());
		pt2.setOnFinished(e -> Platform.exit());
		return pt1;
	}

	private void tripleSpread(ObservableList<Node> children) {
		// 初期化
		removeTarot(children);
		// 配置
		List<Tarot> tarot = Tarot.shuffle();
		List<Position> position = Position.random(3);
		for (int i = 0; i < 3; i++) {
			int ms = 400 + 200 * i;
			ScaleTransition size = new ScaleTransition(Duration.millis(ms));
			size.setFromX(1);
			size.setToX(10);
			size.setFromY(1);
			size.setToY(10);
			TranslateTransition pos = new TranslateTransition(Duration.millis(ms));
			int x = 130 + 90 * i;
			pos.setFromX(0);
			pos.setToX(x);
			pos.setFromY(0);
			pos.setToY(stageHeight / 2 - cardY);
			RotateTransition deg = new RotateTransition(Duration.millis(ms));
			int d = position.get(i).getDeg();
			deg.setFromAngle(-540 + d);
			deg.setToAngle(d);

			Node t = children.get(tarot.get(i).getNum());
			ParallelTransition pt = new ParallelTransition(t, size, pos, deg);
			nowPlaying += 1;
			pt.setOnFinished(e -> nowPlaying--);
			pt.play();
		}
	}

	private void removeTarot(ObservableList<Node> children) {
		if (nowPlaying == 0) {
			// 初期化
			for (Tarot tarot : Tarot.values()) {
				Node t = children.get(tarot.getNum());
				ScaleTransition size = new ScaleTransition(Duration.millis(1));
				size.setToX(0);
				size.setToY(0);
				TranslateTransition pos = new TranslateTransition(Duration.millis(1));
				pos.setToX(0);
				pos.setToY(0);
				ParallelTransition pt = new ParallelTransition(t, size, pos);
				pt.play();
			}
		}
	}

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

	enum Tarot {
		J(0), I(1), II(2), III(3), IV(4), V(5), //
		VI(6), VII(7), VIII(8), IX(9), X(10), //
		XI(11), XII(12), XIII(13), XIV(14), XV(15), //
		XVI(16), XVII(17), XVIII(18), XIX(19), XX(20), XXI(21);

		private int num;

		private Tarot(int num) {
			this.num = num;
		}

		int getNum() {
			return num;
		}

		String image() {
			return "img/tarot_" + num + ".jpg";
		}

		static List<Tarot> shuffle() {
			List<Tarot> deck = new ArrayList<>(Arrays.asList(Tarot.values()));
			Collections.shuffle(deck);
			return deck;
		}
	}

	enum Position {
		Upright(0), Reverse(180);
		private int deg;

		private Position(int deg) {
			this.deg = deg;
		}

		int getDeg() {
			return deg;
		}

		static List<Position> random(int size) {
			List<Position> all = Arrays.asList(Position.values());
			List<Position> rnd = new ArrayList<>();
			while (rnd.size() < size * 3) {
				rnd.addAll(all);
			}
			Collections.shuffle(rnd);
			return rnd.subList(0, size);
		}
	}
}
```
なお、ビルドに失敗してアプリ化まで至らなかった。。。