JavaFX制作相同动画的副本 [英] JavaFX Making Copies of Same Animation
问题描述
我正在尝试扩展之前的任务。它是绘制一个风扇并有一个滑块来控制播放速度,同时还有按钮来播放,暂停和反转风扇。下面是我的代码:
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屋!