java - 有没有办法为 GridPane 中的元素添加动画效果

标签 java animation javafx

我正在尝试为 GridPane 中的元素设置动画。我有一个 Unit 类,它代表我要移动的东西。

public class Unit {
    private Text text;
    private Rectangle rectangle;
    private StackPane stackPane;

    public Unit(Text text, Rectangle rectangle) {
        this.text = text;
        this.rectangle = rectangle;
        text.setFill(Color.WHITE);
        stackPane = new StackPane(rectangle, text);
    }

    public Text getText() {
        return text;
    }

    public void setText(Text text) {
        this.text = text;
    }

    public Rectangle getRectangle() {
        return rectangle;
    }

    public void setRectangle(Rectangle rectangle) {
        this.rectangle = rectangle;
    }

    public StackPane getStackPane() {
        return stackPane;
    }

    public void setStackPane(StackPane stackPane) {
        this.stackPane = stackPane;
    }
}

这就是我现在移动东西的方式

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        GridPane gridPane = new GridPane();
        gridPane.setVgap(5);
        gridPane.setHgap(5);

        Unit unit = new Unit(new Text("1"), new Rectangle(50, 50));
        gridPane.add(unit.getStackPane(), 0, 0);

        TranslateTransition translateTransition = new TranslateTransition();
        translateTransition.setDuration(Duration.seconds(6));
        translateTransition.setToX(200);
        translateTransition.setToY(200);
        translateTransition.setNode(unit.getStackPane());
        translateTransition.play();

        Scene scene = new Scene(gridPane, 300, 275);
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

    }
}

有没有办法将单元移动到特定的行-列位置。我认为 gridpane 可能不适合我的目的,但它是按照我想要的方式布局内容的简单方法。

最佳答案

这是一个基于布局动画器的示例 Animation upon layout changes (也在要点 https://gist.github.com/jewelsea/5683558 中)。我真的不知道这是否真的是您正在寻找的(可能非常接近)。但无论如何,它都非常整洁;-)

我不会在这里过多解释它,因为关于它是什么以及它如何工作的主要解释是在之前链接的问题中。

引用的 Unit 类是您问题中的类。

AnimatedSparseGrid.java

import javafx.animation.*;
import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Point2D;
import javafx.scene.*;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.*;

public class AnimatedSparseGrid extends Application {    
    private static final int NUM_UNITS = 10;
    private static final int UNIT_SIZE = 30;
    private static final int GRID_SIZE = 5;
    private static final int GAP = 5;
    private static final Duration PAUSE_DURATION = Duration.seconds(3);

    private Random random = new Random(42);

    private ObservableList<Unit> units = FXCollections.observableArrayList();

    private GridPane gridPane = new GridPane();

    @Override
    public void start(Stage stage) throws Exception {
        configureGrid();

        LayoutAnimator animator = new LayoutAnimator();
        animator.observe(gridPane.getChildren());

        generateUnits();
        relocateUnits();

        continuouslyAnimateGrid();

        stage.setScene(new Scene(gridPane));
        stage.setResizable(false);
        stage.show();
    }

    private void configureGrid() {
        gridPane.setVgap(GAP);
        gridPane.setHgap(GAP);
        int size = GRID_SIZE * UNIT_SIZE + GAP * (GRID_SIZE - 1);
        gridPane.setMinSize(size, size);
        gridPane.setMaxSize(size, size);
    }

    private void generateUnits() {
        for (int i = 0; i < NUM_UNITS; i++) {
            Unit unit = new Unit(
                    new Text((i + 1) + ""),
                    new Rectangle(UNIT_SIZE, UNIT_SIZE)
            );

            units.add(unit);
        }
    }

    private void relocateUnits() {
        Set<Point2D> usedLocations = new HashSet<>();

        for (Unit unit : units) {
            Node node = unit.getStackPane();

            int col;
            int row;
            do {
                col = random.nextInt(GRID_SIZE);
                row = random.nextInt(GRID_SIZE);
            } while (usedLocations.contains(new Point2D(col, row)));
            usedLocations.add(new Point2D(col, row));

            GridPane.setConstraints(unit.getStackPane(), col, row);

            if (!gridPane.getChildren().contains(node)) {
                gridPane.add(node, col, row);
            }
        }
    }

    private void continuouslyAnimateGrid() {
        Timeline timeline = new Timeline(
                new KeyFrame(Duration.ZERO, event -> relocateUnits()),
                new KeyFrame(PAUSE_DURATION)
        );
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
    }

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

关于java - 有没有办法为 GridPane 中的元素添加动画效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59269930/

相关文章:

java - ToggleButton 在取消选择后保持以前的颜色

java - 如何在 JavaFX 中锁定按钮的位置?

java - 最快的高斯模糊实现

java - 如何使用jdt core代替ecj进行批量编译

c# - 在 WPF 3D 中旋转 360 度

javascript - 动画自定义矢量形状

java - GridPane 未居中对齐

java - 根据 SQL select 语句中的条件检查添加结果列

java - websphere 端口冲突导致应用程序服务器无法启动

iOS:查看翻译动画。合适的方式。