使用JAVAFX和SceneBuilder实现对象线的动态动画

使用JAVAFX和SceneBuilder实现对象线的动态动画,java,javafx,Java,Javafx,我正在寻找一个系统来渲染这个带有变量变化的线动态动画: public class FXMLDocumentController implements Initializable { private long batt = 0; @FXML private Line lancettaBatteria; public long mappa(long x, long in_min, long in_max, long out_min, long out_max)

我正在寻找一个系统来渲染这个带有变量变化的线动态动画:

public class FXMLDocumentController implements Initializable {

    private long batt = 0;

    @FXML
    private Line lancettaBatteria;

    public long mappa(long x, long in_min, long in_max, long out_min, long out_max) {
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {


        Random random = new Random();
        batt = random.nextInt(100);

        long valMappatoBatteria = this.mappa(batt, 0, 100, -40, 135);
        Rotate rotazioneBatteria = new Rotate();

        lancettaBatteria.getTransforms().add(rotazioneBatteria);

        Timeline timelineBatteria = new Timeline(
                new KeyFrame(Duration.ZERO, new KeyValue(rotazioneBatteria.angleProperty(), -40)),
                new KeyFrame(Duration.seconds(3), new KeyValue(rotazioneBatteria.angleProperty(), valMappatoBatteria)));
        timelineBatteria.play();
}
使用此代码,它只显示第一个随机数,我的目标是移动无限时间相对随机生成的(我需要在特定位置显示该行的随机数),这可能吗?我尝试在一段时间内对所有行进行排序(true)


但应用程序停止工作。

通用方法

通常,Java中的无限动画可以通过多种方式实现

以下是一些:

  • 将“无限期”设置为永久播放动画:

    Timeline.setCycleCount(Timeline.INDEFINITE);
    
    如果您希望它来回移动,也可以将AutoReverse设置为true

  • 使用一个

  • 使用时间线并向时间线添加未完成的处理程序,该处理程序会根据需要更新时间线内的一些相关关键帧,然后重新开始播放时间线

  • 使用onFinishedHandler的第三种方法是下面特定示例中遵循的方法

    具体示例

    这个例子是基于我所理解的你问题的要求。我不知道你为什么要这样做。但就我所理解的你要做的,下面的应用程序可以做到

    每次旋转的起始位置:

    旋转的随机最大位置:

    它所做的是创建一个时间线,该时间线将连续更新直线旋转变换中的值。直线从开始旋转角度开始,动画设置为随机最大值,然后动画设置为返回。一旦直线到达其开始位置,将生成新的旋转随机最大值,直线动画设置为t该过程无限期地继续。时间轴动画的setOnFinishedHandler是计算新的随机最大值并适当更新最大动画值的关键帧的点

    所以,这可能正是你想要做的,也可能不是,但也许它足以让你实现你所需要的

    import javafx.animation.*;
    import javafx.application.Application;
    import javafx.beans.property.*;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.Pane;
    import javafx.scene.shape.Line;
    import javafx.scene.transform.Rotate;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    
    import java.util.Random;
    
    public class VariableLine extends Application {
        private static final double S = 100;
    
        @Override
        public void start(Stage stage) throws Exception {
            RandomRotator randomRotator = new RandomRotator();
    
            Line line = new Line(0, S, S, S);
            randomRotator.getRotate().setPivotY(S);
            line.getTransforms().add(randomRotator.getRotate());
    
            Label maxValueText = new Label(randomRotator.getMaxAngle() + "");
            maxValueText.textProperty().bind(randomRotator.maxAngleProperty().asString());
    
            stage.setScene(new Scene(new Pane(maxValueText, line), S, S * 2));
            stage.show();
    
            randomRotator.getTimeline().play();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    class RandomRotator {
        private static final Random random = new Random(42);
    
        private static final double INIT_ANGLE = -40;
        private static final double MAX_ANGLE = 90;
        private static final Duration ROTATION_DURATION = Duration.seconds(3);
    
        private final ReadOnlyDoubleWrapper maxAngle = new ReadOnlyDoubleWrapper(INIT_ANGLE);
        private final Timeline timeline = new Timeline();
        private final Rotate rotate = new Rotate(INIT_ANGLE);
    
        RandomRotator() {
            timeline.getKeyFrames().addAll(
                new KeyFrame(
                        Duration.seconds(0),
                        new KeyValue(rotate.angleProperty(), INIT_ANGLE)
                ),
                new KeyFrame(
                        ROTATION_DURATION.divide(2), 
                        new KeyValue(rotate.angleProperty(), maxAngle.get())
                ),
                new KeyFrame(
                        ROTATION_DURATION,
                        new KeyValue(rotate.angleProperty(), INIT_ANGLE)
                )
            );
    
            timeline.setOnFinished(event -> {
                maxAngle.set(random.nextInt((int) MAX_ANGLE));
                timeline.getKeyFrames().set(
                        1,
                        new KeyFrame(
                                ROTATION_DURATION.divide(2), 
                                new KeyValue(rotate.angleProperty(), maxAngle.get())
                        )
                );
                timeline.playFromStart();
            });
        }
    
        Rotate getRotate() {
            return rotate;
        }
    
        public double getMaxAngle() {
            return maxAngle.get();
        }
    
        public ReadOnlyDoubleProperty maxAngleProperty() {
            return maxAngle.getReadOnlyProperty();
        }
    
        public Timeline getTimeline() {
            return timeline;
        }
    }
    

    是的,但这不会刷新另一个随机数,谢谢当值更改时,使用旧的vslue停止时间线,使用新值创建新的时间线并启动新的时间线。或者使用AnimationTimer。我的目标是:使用生成的相对随机数无限时间移动线。2步骤1)生成随机数2)为该随机数制作动画,并重复步骤1和2,。。。。
    import javafx.animation.*;
    import javafx.application.Application;
    import javafx.beans.property.*;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.Pane;
    import javafx.scene.shape.Line;
    import javafx.scene.transform.Rotate;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    
    import java.util.Random;
    
    public class VariableLine extends Application {
        private static final double S = 100;
    
        @Override
        public void start(Stage stage) throws Exception {
            RandomRotator randomRotator = new RandomRotator();
    
            Line line = new Line(0, S, S, S);
            randomRotator.getRotate().setPivotY(S);
            line.getTransforms().add(randomRotator.getRotate());
    
            Label maxValueText = new Label(randomRotator.getMaxAngle() + "");
            maxValueText.textProperty().bind(randomRotator.maxAngleProperty().asString());
    
            stage.setScene(new Scene(new Pane(maxValueText, line), S, S * 2));
            stage.show();
    
            randomRotator.getTimeline().play();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    class RandomRotator {
        private static final Random random = new Random(42);
    
        private static final double INIT_ANGLE = -40;
        private static final double MAX_ANGLE = 90;
        private static final Duration ROTATION_DURATION = Duration.seconds(3);
    
        private final ReadOnlyDoubleWrapper maxAngle = new ReadOnlyDoubleWrapper(INIT_ANGLE);
        private final Timeline timeline = new Timeline();
        private final Rotate rotate = new Rotate(INIT_ANGLE);
    
        RandomRotator() {
            timeline.getKeyFrames().addAll(
                new KeyFrame(
                        Duration.seconds(0),
                        new KeyValue(rotate.angleProperty(), INIT_ANGLE)
                ),
                new KeyFrame(
                        ROTATION_DURATION.divide(2), 
                        new KeyValue(rotate.angleProperty(), maxAngle.get())
                ),
                new KeyFrame(
                        ROTATION_DURATION,
                        new KeyValue(rotate.angleProperty(), INIT_ANGLE)
                )
            );
    
            timeline.setOnFinished(event -> {
                maxAngle.set(random.nextInt((int) MAX_ANGLE));
                timeline.getKeyFrames().set(
                        1,
                        new KeyFrame(
                                ROTATION_DURATION.divide(2), 
                                new KeyValue(rotate.angleProperty(), maxAngle.get())
                        )
                );
                timeline.playFromStart();
            });
        }
    
        Rotate getRotate() {
            return rotate;
        }
    
        public double getMaxAngle() {
            return maxAngle.get();
        }
    
        public ReadOnlyDoubleProperty maxAngleProperty() {
            return maxAngle.getReadOnlyProperty();
        }
    
        public Timeline getTimeline() {
            return timeline;
        }
    }