You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaFX中逐个播放StrokeTransition类型ArrayList的动画?

实现JavaFX线条动画逐个依次播放的方案

我明白你想要的效果:让trans列表里的每个StrokeTransition动画按顺序逐个播放,完成一个线条的颜色过渡后,再启动下一个。你的现有代码已经正确创建了线条和对应的动画,但缺少按顺序触发动画的逻辑,默认直接启动所有动画会导致它们同时播放。下面给你两种简单的解决方法:

方法1:用SequentialTransition(推荐,代码更简洁)

JavaFX提供了SequentialTransition类,专门用来按顺序执行多个动画,非常适合你的场景。在你现有代码的末尾添加以下代码即可:

// 创建序列动画容器,用来按顺序执行所有线条动画
SequentialTransition sequentialAnim = new SequentialTransition();
// 将trans列表中的所有动画添加到序列中
sequentialAnim.getChildren().addAll(trans);
// 启动整个序列动画
sequentialAnim.play();

// 可选:如果需要循环播放整个序列,可以添加这行
// sequentialAnim.setCycleCount(Animation.INDEFINITE);

为什么好用?

  • 不需要手动处理动画的结束回调,JavaFX会自动管理顺序
  • 支持暂停、继续、重置等操作,方便控制整个动画流程
  • 动画顺序完全遵循trans列表中元素的添加顺序,和你创建线条的顺序一致

方法2:手动通过setOnFinished链式触发

如果你不想用容器类,也可以手动给每个动画设置结束回调,让前一个动画完成后自动启动下一个:

// 确保trans列表不为空再执行
if (!trans.isEmpty()) {
    // 给每个动画(除了最后一个)设置结束回调
    for (int i = 0; i < trans.size() - 1; i++) {
        int currentIndex = i;
        trans.get(i).setOnFinished(event -> {
            // 当前动画结束后,启动下一个动画
            trans.get(currentIndex + 1).play();
        });
    }
    // 手动启动第一个动画,开启整个链式流程
    trans.get(0).play();
}

注意事项

  1. 动画顺序:确保trans列表中的动画顺序和你想要播放的线条顺序一致,因为序列是严格按照列表顺序执行的
  2. 时长调整:你当前设置的动画时长是10秒(Duration.millis(10000)),如果觉得太长可以修改这个数值,比如改成2秒就是Duration.millis(2000)
  3. 线条样式:如果需要在动画结束后保持最终颜色(蓝色),你的StrokeTransition已经设置了从CYAN到BLUE的过渡,结束后会自动保留BLUE,不需要额外处理

整理后的完整代码参考

import javafx.animation.Animation;
import javafx.animation.SequentialTransition;
import javafx.animation.StrokeTransition;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.util.Duration;
import java.util.ArrayList;

// ... 你的其他代码 ...

int a = 0;
ArrayList<Line> nodeline = new ArrayList<Line>();
ArrayList<StrokeTransition> trans = new ArrayList<StrokeTransition>();
ArrayList<Double> lineaxisx = new ArrayList<Double>();
ArrayList<Double> lineaxisy = new ArrayList<Double>();

for(int i = 0; i < dainput.size(); i += 3) {
    lineaxisx.add((double)axisx.get(dainput.get(i)));
    lineaxisx.add((double)axisx.get(dainput.get(i+1)));
    lineaxisy.add((double)axisy.get(dainput.get(i)));
    lineaxisy.add((double)axisy.get(dainput.get(i+1)));
    
    nodeline.add(new Line(
        axisx.get(dainput.get(i)),
        axisy.get(dainput.get(i)),
        axisx.get(dainput.get(i+1)),
        axisy.get(dainput.get(i+1))
    ));
    nodeline.get(a).setStroke(Color.CYAN);
    
    for(int j = 0; j < daiout.size(); j += 3){
        if(daiout.get(j) == dainput.get(i) 
           && daiout.get(j+1) == dainput.get(i + 1) 
           && daiout.get(j + 2) == dainput.get(i + 2)){
            trans.add(new StrokeTransition(
                Duration.millis(10000), 
                nodeline.get(a), 
                Color.CYAN, 
                Color.BLUE
            ));
        }
    }
    
    root.getChildren().addAll(nodeline.get(a));
    a++;
}

// 这里添加顺序播放的逻辑(二选一即可)
// 方法1:SequentialTransition
SequentialTransition sequentialAnim = new SequentialTransition();
sequentialAnim.getChildren().addAll(trans);
sequentialAnim.play();

// 方法2:手动链式触发(注释掉方法1后启用)
/*
if (!trans.isEmpty()) {
    for (int i = 0; i < trans.size() - 1; i++) {
        int currentIndex = i;
        trans.get(i).setOnFinished(event -> {
            trans.get(currentIndex + 1).play();
        });
    }
    trans.get(0).play();
}
*/

内容的提问来源于stack exchange,提问作者Hawk3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:24:31