JavaFX制作相同动画的副本 [英] JavaFX Making Copies of Same Animation

查看:116
本文介绍了JavaFX制作相同动画的副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试扩展之前的任务。它是绘制一个风扇并有一个滑块来控制播放速度,同时还有按钮来播放,暂停和反转风扇。下面是我的代码:

I am attempting to expand on a previous assignment. It was to draw a fan and have a slider to control the play speed, along with having buttons to play, pause, and reverse the fans. Here is my code for that assignment:

public class FanWithControls extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
    FanPane fan = new FanPane();
    StackPane spane = new StackPane();
    spane.getChildren().addAll(fan);
    HBox hBox = new HBox(5);
    Button btPause = new Button("Pause");
    Button btResume = new Button("Resume");
    Button btReverse = new Button("Reverse");
    hBox.setAlignment(Pos.CENTER);
    hBox.getChildren().addAll(btPause, btResume, btReverse); 
    Slider slider = new Slider(0,10, 3);
    slider.setShowTickLabels(true);
    slider.setShowTickMarks(true);

    BorderPane pane = new BorderPane();
    pane.setCenter(spane);
    pane.setTop(hBox);
    pane.setBottom(slider);

    // Create a scene and place it in the stage
    Scene scene = new Scene(pane, 300, 400);
    primaryStage.setTitle("FanWithControls"); // Set the stage title
    primaryStage.setScene(scene); // Place the scene in the stage
    primaryStage.show(); // Display the stage

    Timeline animation = new Timeline(
                                      new KeyFrame(Duration.millis(50), e ->      fan.move()));
    animation.setCycleCount(Timeline.INDEFINITE);
    animation.play(); // Start animation

    scene.widthProperty().addListener(e -> fan.setW(fan.getWidth()));
    scene.heightProperty().addListener(e -> fan.setH(fan.getHeight()));

    btPause.setOnAction(e -> animation.pause());
    btResume.setOnAction(e -> animation.play());
    btReverse.setOnAction(e -> fan.reverse());

    slider.valueProperty().addListener(ov -> animation.setRate(slider.getValue()));

}

/**
 * The main method is only needed for the IDE with limited
 * JavaFX support. Not needed for running from the command line.
 */
public static void main(String[] args) {
    launch(args);
}
}
class FanPane extends Pane {
private double w = 200;
private double h = 200;
private double radius = Math.min(w, h) * 0.45;
private Arc arc[] = new Arc[4];
private double startAngle = 30;
private Circle circle = new Circle(w / 2, h / 2, radius);


public FanPane() {
    circle.setStroke(Color.BLUE);
    circle.setFill(Color.WHITE);
    circle.setStrokeWidth(4);
    getChildren().add(circle);

    for (int i = 0; i < 4; i++) {
        arc[i] = new Arc(w / 2, h / 2, radius * 0.9, radius * 0.9,    startAngle + i * 90, 35);
        arc[i].setFill(Color.RED); // Set fill color
        arc[i].setType(ArcType.ROUND);
        getChildren().addAll(arc[i]);
    }
}

private double increment = 5;

public void reverse() {
    increment = -increment;
}

public void move() {
    setStartAngle(startAngle + increment);
}

public void setStartAngle(double angle) {
    startAngle = angle;
    setValues();
}

public void setValues() {
    radius = Math.min(w, h) * 0.45;
    circle.setRadius(radius);
    circle.setCenterX(w / 2);
    circle.setCenterY(h / 2);


    for (int i = 0; i < 4; i++) {
        arc[i].setRadiusX(radius * 0.9);
        arc[i].setRadiusY(radius * 0.9);
        arc[i].setCenterX(w / 2);
        arc[i].setCenterY(h / 2);
        arc[i].setStartAngle(startAngle + i * 90);
    }
}

public void setW(double w) {
    this.w = w;
    setValues();
}

public void setH(double h) {
    this.h = h;
    setValues();
}

public double getCenterX() {
  return circle.getCenterX();
}

public double getCenterY() {
  return circle.getCenterY();
}

public double getRadius() {
  return circle.getRadius();
}
}

我想知道是否有人可以帮助我。我很难让这个工作起来。我已经尝试制作一个包含多个fanpanes的hbox,但是当我调整框大小时它们会缩小并且不会增长。

I was wondering if anyone could help me with this. I am having an extremely hard time getting this to work. Ive tried making an hbox that contains multiple fanpanes but they shrink in size and dont grow when I resize the box.

基本上我试图让它成为一个滑块,让你最多可以拥有5个扇形窗。增加它将增加更多的扇形,减少它将带走它们等。

Basically I am trying to make it so you can have a slider that will allow you to have up to 5 fanpanes. Increasing it will add more fanpanes, decreasing it will take them away, etc.

任何提示或帮助将不胜感激,谢谢!

Any tips or help would be greatly appreciated thank you!

推荐答案

使用 FlowPane 代替 StackPane 并在 FanPane 类中声明动画。这是代码

Use FlowPane instead of StackPane and declare the Animation inside FanPane class. Here's the code

public class FanWithControls extends Application {

    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        FanPane fan = new FanPane();
        FlowPane spane = new FlowPane();
        spane.getChildren().addAll(fan);
        HBox hBox = new HBox(5);
        Button btPause = new Button("Pause");
        Button btResume = new Button("Resume");
        Button btReverse = new Button("Reverse");
        hBox.setAlignment(Pos.CENTER);
        hBox.getChildren().addAll(btPause, btResume, btReverse);
        Slider slider = new Slider(0, 10, 3);
        slider.setShowTickLabels(true);
        slider.setShowTickMarks(true);

        BorderPane pane = new BorderPane();
        pane.setCenter(spane);
        pane.setTop(hBox);
        pane.setBottom(slider);

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane, 300, 400);
        primaryStage.setTitle("FanWithControls"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage

        fan.setAnimation(fan);
        Timeline animation = fan.getAnimation();

        scene.widthProperty().addListener(e -> fan.setW(fan.getWidth()));
        scene.heightProperty().addListener(e -> fan.setH(fan.getHeight()));

        btPause.setOnAction((e) -> {
            for (Node fans : spane.getChildren()) {
                FanPane fanpane = (FanPane) fans;
                fanpane.getAnimation().pause();
            }
//            animation.pause();
        });
        btResume.setOnAction((e) -> {
            for (Node fans : spane.getChildren()) {
                FanPane fanpane = (FanPane) fans;
                fanpane.getAnimation().play();
            }
//            animation.play();
        });
        btReverse.setOnAction((e) -> {
            for (Node fans : spane.getChildren()) {
                FanPane fanpane = (FanPane) fans;
                fanpane.reverse();
            }
//            fan.reverse();
        });

        slider.valueProperty().addListener((ov) -> {
//            animation.setRate(slider.getValue());
            for (Node fans : spane.getChildren()) {
                FanPane fanpane = (FanPane) fans;
                fanpane.getAnimation().setRate(slider.getValue());
            }
            if (spane.getChildren().size() < (int) slider.getValue()) {
                for (int i = spane.getChildren().size(); i < (int) slider.getValue(); i++) {
                    FanPane fanPane = new FanPane();
                    spane.getChildren().add(fanPane);
                    fanPane.setAnimation(fanPane);
                    fanPane.getAnimation().setRate(slider.getValue());
                }
            } else if (spane.getChildren().size() > (int) slider.getValue()) {
                for (int i = (int) slider.getValue(); i < spane.getChildren().size(); i++) {
                    spane.getChildren().remove(spane.getChildren().size() - 1);
                }
            }
        });

    }

    /**
     * The main method is only needed for the IDE with limited JavaFX support.
     * Not needed for running from the command line.
     */
    public static void main(String[] args) {
        launch(args);
    }

    class FanPane extends Pane {

        private double w = 200;
        private double h = 200;
        private double radius = Math.min(w, h) * 0.45;
        private Arc arc[] = new Arc[4];
        private double startAngle = 30;
        private Circle circle = new Circle(w / 2, h / 2, radius);
        private Timeline animation;

        public FanPane() {
            circle.setStroke(Color.BLUE);
            circle.setFill(Color.WHITE);
            circle.setStrokeWidth(4);
            getChildren().add(circle);

            for (int i = 0; i < 4; i++) {
                arc[i] = new Arc(w / 2, h / 2, radius * 0.9, radius * 0.9, startAngle + i * 90, 35);
                arc[i].setFill(Color.RED); // Set fill color
                arc[i].setType(ArcType.ROUND);
                getChildren().addAll(arc[i]);
            }

        }

        public Timeline getAnimation() {
            return animation;
        }

        public void setAnimation(FanPane fan) {
            this.animation = new Timeline(new KeyFrame(Duration.millis(50), e -> fan.move()));
            animation.setCycleCount(Timeline.INDEFINITE);
            animation.play();
        }

        private double increment = 5;

        public void reverse() {
            increment = -increment;
        }

        public void move() {
            setStartAngle(startAngle + increment);
        }

        public void setStartAngle(double angle) {
            startAngle = angle;
            setValues();
        }

        public void setValues() {
            radius = Math.min(w, h) * 0.45;
            circle.setRadius(radius);
            circle.setCenterX(w / 2);
            circle.setCenterY(h / 2);

            for (int i = 0; i < 4; i++) {
                arc[i].setRadiusX(radius * 0.9);
                arc[i].setRadiusY(radius * 0.9);
                arc[i].setCenterX(w / 2);
                arc[i].setCenterY(h / 2);
                arc[i].setStartAngle(startAngle + i * 90);
            }
        }

        public void setW(double w) {
            this.w = w;
            setValues();
        }

        public void setH(double h) {
            this.h = h;
            setValues();
        }

        public double getCenterX() {
            return circle.getCenterX();
        }

        public double getCenterY() {
            return circle.getCenterY();
        }

        public double getRadius() {
            return circle.getRadius();
        }

    }
}

这篇关于JavaFX制作相同动画的副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆