I have some code in which I am trying to display seven unique "squares" of characters. There is a "Shuffle" button - upon clicking the characters should change sequence. There is also a "flying" effect added. The shuffle and flying effects are working, but the spacing of the squares in the GridPane gets messed up upon shuffling. Great if someone can help. Here is the code:
package com.example.javafxdemo.shuffle;
import javafx.animation.ParallelTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.*;
public class ShuffleGridPaneExample_Animation_BUGGY_BUT_CLOSE_1_DEBUG extends Application {
private final int gridSize = 7; // Number of columns in the grid
private final int squareSize = 80; // Size of each square
private final GridPane gridPane = new GridPane();
private final List<Square> squares = new ArrayList<>();
@Override
public void start(Stage primaryStage) {
createGridPane();
Button shuffleButton = new Button("Shuffle");
shuffleButton.setOnAction(event -> shuffleSquares());
GridPane root = new GridPane();
root.setAlignment(Pos.CENTER);
root.add(gridPane, 0, 0);
root.add(shuffleButton, 0, 1);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Shuffle GridPane Example");
primaryStage.show();
}
private void createGridPane() {
Random random = new Random();
for (int i = 0; i < gridSize; i++) {
Square square = createSquare(generateRandomLetter(random), i);
squares.add(square);
gridPane.add(square, i, 0);
}
}
static HashSet<Integer> generatedLetters = new LinkedHashSet<>();
private char generateRandomLetter(Random random) {
while (true) {
int letterIndex = random.nextInt(26); // Generate a random index between 0 and 25
if (generatedLetters.contains(letterIndex)) {
continue;
}
return (char) ('A' + letterIndex); // Convert the index to the corresponding letter (A-Z)
}
}
private Square createSquare(char letter, int columnIndex) {
Square square = new Square(squareSize, squareSize, letter, columnIndex);
GraphicsContext gc = square.getGraphicsContext2D();
gc.setFill(generateRandomColor());
gc.fillRect(0, 0, squareSize, squareSize);
gc.setFill(Color.BLACK);
gc.setFont(Font.font("Arial", FontWeight.BOLD, 40));
gc.fillText(String.valueOf(letter), squareSize / 2 - 10, squareSize / 2 + 10);
return square;
}
private void shuffleSquares() {
Collections.shuffle(squares);
gridPane.getChildren().clear();
int columnIndex = 0;
for (Square square : squares) {
gridPane.add(square, columnIndex, 0);
columnIndex++;
}
animateTileMovement();
}
private void animateTileMovement() {
ParallelTransition parallelTransition = new ParallelTransition();
for (int i = 0; i < gridSize; i++) {
Square square = squares.get(i);
int targetIndex = gridPane.getColumnIndex(square);
if (square.getOriginalIndex() != targetIndex) {
double startX = square.getLayoutX();
double targetX = targetIndex * squareSize;
TranslateTransition translateTransition = new TranslateTransition(Duration.seconds(3), square);
translateTransition.setFromX(startX);
translateTransition.setToX(targetX);
// Add the flying effect
double startY = square.getLayoutY() - squareSize;
translateTransition.setFromY(startY);
double targetY = square.getLayoutY();
translateTransition.setToY(targetY);
System.out.println(i + "'" + square.letter + "' (" + startX + ", " + startY + ") (" + targetX + ", " + targetY + ")");
parallelTransition.getChildren().add(translateTransition);
}
}
parallelTransition.play();
}
public static void main(String[] args) {
launch(args);
}
private static class Square extends Canvas {
private final int originalIndex;
private final char letter;
public Square(double width, double height, char letter, int originalIndex) {
super(width, height);
this.originalIndex = originalIndex;
this.letter = letter;
}
public int getOriginalIndex() {
return originalIndex;
}
}
private Color generateRandomColor() {
Random random = new Random();
double r = random.nextDouble();
double g = random.nextDouble();
double b = random.nextDouble();
return new Color(r, g, b, 1.0);
}
}