7

I'm new to animation with fx, I'm trying to have one animation play right after the other one finishes. But instead of that, both of the animation play at the same time on separate side of the stage. Additionally, is there a way to change the size of the images that are displayed via JavaFX without changing the pixel size of the image?

I tried setting the layout x and y of the animation to be the same so it would be played on top of each other.

package application;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;

public class Main extends Application {

    // LOAD IMAGES======================================================================

    // load in sun images
    final static javafx.scene.image.Image sun1 = new javafx.scene.image.Image(
            Main.class.getResource("/Sun/Sun1.png").toString());
    final static javafx.scene.image.Image sun2 = new javafx.scene.image.Image(

    // load in rain images
    final static javafx.scene.image.Image rain1 = new javafx.scene.image.Image(
            Main.class.getResource("/Rain/Rain1.png").toString());
    final static javafx.scene.image.Image rain2 = new javafx.scene.image.Image(
            Main.class.getResource("/Rain/Rain2.png").toString());

    // create a group node
    private Group sunGrp;
    private Group rainGrp;

    @Override
    public void start(Stage primaryStage) {

        // CREATE IMAGE VIEWS ==================================================================================

        // sun ImageView
        final ImageView sun1IV = new ImageView(sun1);
        final ImageView sun2IV = new ImageView(sun2);

        // rain ImageView
        final ImageView rain1IV = new ImageView(rain1);
        final ImageView rain2IV = new ImageView(rain2);

        // PUT IMAGEVIEW INTO GROUP
        rainGrp = new Group(rain1IV);
        rainGrp.setLayoutX(100);
        rainGrp.setLayoutY(120);

        sunGrp = new Group(sun1IV);
        sunGrp.setLayoutX(100);
        sunGrp.setLayoutY(120);
        //sunGrp.setTranslateX(100);
        //sunGrp.setTranslateY(120);


        // ANIMATE IMAGES INTO A LOOP ===========================================================

        // sun animation
        Timeline sunT = new Timeline();
        sunT.setCycleCount(2);

        // add images into the time line
        sunT.getKeyFrames().add(new KeyFrame(Duration.millis(100), (ActionEvent event) -> {
            sunGrp.getChildren().setAll(sun1IV);
        }));
        sunT.getKeyFrames().add(new KeyFrame(Duration.millis(200), (ActionEvent event) -> {
            sunGrp.getChildren().setAll(sun2IV);
        }));

        Timeline rainT = new Timeline();
        rainT.setCycleCount(2);

        rainT.getKeyFrames().add(new KeyFrame(Duration.millis(100), (ActionEvent event) -> {
            rainGrp.getChildren().setAll(rain1IV);
        }));
        rainT.getKeyFrames().add(new KeyFrame(Duration.millis(200), (ActionEvent event) -> {
            rainGrp.getChildren().setAll(rain2IV);
        }));


        sunT.play();
        rainT.play();

        HBox hi = new HBox();
        hi.getChildren().addAll(sunGrp,rainGrp);

        primaryStage.setScene(new Scene(hi, 800, 800));

        primaryStage.setTitle("Cloud");
        primaryStage.show();

    }// end start

    public static void main(String[] args) {
        launch(args);
    }
}

Expecting: One animation play, finish, and the next animation play right on top.

Current error: Both animation play at the same time on separate side of the stage.

Update: Changed HBox to StackPane and it seems to be only playing one animation only. Is there a method that "remove" the animation so the next one play? Or it is suppose to be playing on top?

Update 2: I got it work, my actual program have 10 images per animations. I'm guessing both of them play at the same time so it wasn't able to play one at a time. rainT.play();

        sunT.play();
        rainT.play();

is replaced by

        rainT.setOnFinished(event -> {
            rainGrp.setVisible(false);
            sunT.play();
        });
Truong Nguyen
  • 201
  • 2
  • 9
  • 1
    Try `StackPane`, seen [here](https://stackoverflow.com/a/55663730/230513), which "lays out its children in a back-to-front stack." – trashgod Jul 20 '19 at 03:26
  • @trashgod swapping from HBox to StackPane did solve the issue of showing both animations at the same time but did not do the overlapping. It's playing one animation only now. – Truong Nguyen Jul 20 '19 at 04:11
  • 2
    Your animation is very short. I suspect it ends before `primaryStage.show();` . Move `sunT.play(); rainT.play();` to after `primaryStage.show();` and make your animation longer. Also see [SequentialTransition](https://docs.oracle.com/javafx/2/api/javafx/animation/SequentialTransition.html) . Also consider using the [on finished event](https://docs.oracle.com/javase/8/javafx/api/javafx/animation/Animation.html#setOnFinished-javafx.event.EventHandler-) – c0der Jul 20 '19 at 06:25
  • You may need to switch to an image format the supports transparency and alter the node's `BlendMode`. – trashgod Jul 20 '19 at 08:26
  • good to provide a [mcve], +1 :) Strictly speaking, it's not quite reproducible - we don't have the images. Not such a big deal (we can easily replace them with something on our computers or the web), but maybe we are lazy - so you might consider replacing them with something available for all (icons in the framework or web resources) – kleopatra Jul 20 '19 at 12:40

0 Answers0