时间轴动画JavaFX

我想知道为什么我的屏幕在每次移动图表后都没有清除 . 那是我的代码:

MainClass,我想从那里删除“时间”并将其放入Drawing方法updateScene中的lambda expresion中,但是不知道该怎么做:/

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;


public class MainClass extends Application{
    private Drawing draw;
    private double time = 0;
    public static void main(String[] args) {
        launch(args);
    }
       @Override
        public void start(final Stage stage) {
           Group root = new Group();
           root.setStyle("-fx-background-color: rgb(35, 39, 50);"); 
           stage.setScene(new Scene(root, 1000, 1000,  Color.rgb(35, 39, 50))); 

        while(time < 2 ) {
               draw = new Drawing(root, time);
               time+=0.1;

               draw.updateScene();
               stage.show();     
           }
       }
}

Axes类描述了如何绘制轴:

import javafx.beans.binding.Bindings;
import javafx.geometry.Side;
import javafx.scene.chart.NumberAxis;
import javafx.scene.layout.Pane;

public class Axes extends Pane{
    private NumberAxis xAxis;
    private NumberAxis yAxis;

    public Axes(int width, int height, 
            double xMin, double xMax, double xTickUnit, 
            double yMin, double yMax, double yTickUnit) {
        setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
        setPrefSize(width, height);
        setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);

        xAxis = new NumberAxis(xMin, xMax, xTickUnit);
        xAxis.setSide(Side.BOTTOM);
        xAxis.setMinorTickVisible(false);
        xAxis.setPrefWidth(width);
        xAxis.setLayoutY(height/2);

        yAxis = new NumberAxis(yMin, yMax, yTickUnit);
        yAxis.setSide(Side.LEFT);
        yAxis.setMinorTickVisible(false);
        yAxis.setPrefHeight(height);
        yAxis.layoutXProperty().bind(Bindings.subtract((width / 2) + 1, yAxis.widthProperty()));

        getChildren().setAll(xAxis, yAxis);
    }

    public NumberAxis getXAxis() {
        return xAxis;
    }

    public NumberAxis getYAxis() {
        return yAxis;
    }

}

在图表中缩放和绘制我需要的所有内容 .

import java.util.function.Function;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;

public class Chart extends Pane {

    public Chart(Function<Double, Double> f,
            double xMin, double xMax, double xInc,
            Axes axes ) {
        Path path = new Path();
        path.setStroke(Color.ORANGE.deriveColor(0, 1, 1,0.5));
        path.setStrokeWidth(1);
        path.setClip(new Rectangle(0, 0, axes.getPrefWidth(), axes.getPrefHeight()));


        double x = xMin;
        double y = f.apply(x);


        path.getElements().add(new MoveTo(
                mapX(x, axes), mapY(y, axes)
                ));
        x+=xInc;

        while(x < xMax) {
            if(x == xMax) { 
                x = xMin;
                y = f.apply(x);
                path.getElements().add(new MoveTo(
                        mapX(x, axes), mapY(y, axes)
                        ));
            }
            y = f.apply(x);
            path.getElements().add(new LineTo(
                    mapX(x, axes), mapY(y, axes)
                    ));
            x+=xInc;

        }

         setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         setPrefSize(axes.getPrefWidth(), axes.getPrefHeight());
         setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);

         getChildren().setAll(axes, path);
    }



    private double mapX(double x, Axes axes) {
        double fx = axes.getPrefWidth() / 2;
        double sx = axes.getPrefWidth() / 
                (axes.getXAxis().getUpperBound() - axes.getXAxis().getLowerBound());

        return x * fx + sx;
    }

    private double mapY(double y, Axes axes) {
        double fy = axes.getPrefHeight() / 2;
        double sy = axes.getPrefHeight() / 
                (axes.getYAxis().getUpperBound() - axes.getYAxis().getLowerBound());

        return -y * sy + fy;
    }

}

绘图类负责制作动画并精确绘制我想要哪种模式的图表 .

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.Group;
import javafx.util.Duration;

public class Drawing {
    private double t = 0;
    private double l = 1;
    private Group root;

    public Drawing(final Group root, double t) {
        this.root = root;
        this.t = t;
    }

    public void updateScene() {

        final Chart chart = new Chart(x -> Math.exp(-(Math.pow((x-t), 2)))*Math.cos((2*Math.PI*(x-t))/l),
                -1, 1, 0.01, new Axes(1000, 1000,
                        -1, 1, 0.1, -1, 1, 0.1)
                );
        Timeline timeLine = new Timeline(Timeline.INDEFINITE, 
                new KeyFrame(new Duration(1000),
                x -> {          
                    root.getChildren().add(chart);
                }));    
        timeLine.setAutoReverse(true);
        timeLine.play();

    }   
}

屏幕显示我编译后得到的内容 . 就像我提出的问题一样,不知道在每个时间线阶段之后导致不清洁的原因 .

回答(1)

3 years ago

  • 如果您想要对问题给出合理的答案,那么您不应该将所有代码都丢弃在我们身上,而应将代码归结为重现问题的必要条件 .

  • 你的程序的整体概念看起来非常错误 . 如果你想移动你的图表,那么只需移动它,但不要经常创建一个新图表 .

  • 为什么在循环中调用stage.show()?

  • 如果没有时间真正查看所有代码,我会说你的问题是不断重新创建图表 .