如何在JavaFX中使用时间轴更改图像 [英] How to change images with Timeline in JavaFX

查看:60
本文介绍了如何在JavaFX中使用时间轴更改图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算通过将for循环中的关键帧添加到时间轴对象来随时间改变鸟类的图像.事实证明,仅显示第一张图像.有人可以指出我在哪里弄错了.预先感谢.

I intend to change the images of birds over the time by adding key frames in a for loop to the timeline object. It turns out that only the first image is displayed. Could someone point out where part I got it wrong. Thanks in advance.

此外,我注意到我必须在for循环之后将计数器"index"重置为0,否则它将生成java.lang.ArrayIndexOutOfBoundsException.

Besides, I noticed that I have to reset the counter "index" to 0 after for loop otherwise it generates java.lang.ArrayIndexOutOfBoundsException.

打包申请;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.effect.BoxBlur;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;

public class Main extends Application 

{

int index=0;
@Override
public void start(Stage primaryStage) {
    try {

        ImageView bgV = new ImageView();
        Image img_BG = new Image(Main.class.getResourceAsStream("background.png"));
        bgV.setImage(img_BG);
        bgV.setEffect(new BoxBlur());
        bgV.setOpacity(0.5);

        ImageView t1V = new ImageView();
        Image img_t1 = new Image(Main.class.getResourceAsStream(
                "t1.png"
                ));
        t1V.setImage(img_t1);

        ImageView t2V = new ImageView();
        Image img_t2 = new Image(Main.class.getResourceAsStream(
                "t2.png"
                ));
        t2V.setImage(img_t2);

        ImageView t3V = new ImageView();
        Image img_t3 = new Image(Main.class.getResourceAsStream(
                "t3.png"
                ));
        t3V.setImage(img_t3);

        Group foreground = new Group(t1V,t2V,t3V);

        t1V.setTranslateX(20);
        t1V.setTranslateY(200);

        t2V.setTranslateX(300);
        t2V.setTranslateY(200);

        t3V.setTranslateX(550);
        t3V.setTranslateY(200);
        foreground.setEffect(new DropShadow());

        String[]
                birdFiles = {"b1.png", "b2.png", "b3.png", "b4.png", "b5.png", "b6.png"};
        double[] ds = { 300,            600,                900,            1200,   1500,   1800};

        ImageView birdV = new ImageView(new Image(Main.class.getResourceAsStream(birdFiles[0])));
        Group birds = new Group(birdV);
        birds.setTranslateX(img_BG.getWidth()-100);

        Timeline timeline  = new Timeline(); 
        timeline.setCycleCount(
                Animation.INDEFINITE
                ); 


        KeyFrame[] kframs = new KeyFrame[birdFiles.length];

        for( index=0; index<birdFiles.length; index++)
        {
            EventHandler<ActionEvent>
                onFishined = new EventHandler<ActionEvent>()
            {

                @Override
                public void handle(ActionEvent arg0)
                {
                    birds.getChildren().setAll(new ImageView(new Image(Main.class.getResourceAsStream(birdFiles[index]))));

                }

            };
            Duration duration = Duration.millis(ds[index]);
            KeyFrame
                kf = new KeyFrame(duration, onFishined,null,null    );
             timeline.getKeyFrames().add(kf);

        }//End for i
        index = 0;







        timeline.play();





        Group root = new Group(bgV,foreground,birds);

        Scene scene = new Scene(root,img_BG.getWidth(), img_BG.getHeight());
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

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

}

推荐答案

您不必在外部声明index字段.这也会引起您的问题:每当调用handle方法时,它将引用您的字段:index,您在循环后将其设置为0.

you don't have to declare your index-field outside. this also causes your problem: whenever the handle method is called, it will reference your field: index which you set to 0 after your loop.

因此,您可以将新字段声明为final并将其传递给处理程序:

therefor you can declare a new field as finaland pass it to the handler:

for (int index = 0; index < birdFiles.length; index++) {
    final int birdIndex = index;
    EventHandler<ActionEvent> onFishined = new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent arg0) {
                    birds.getChildren().setAll(new ImageView(new Image(Main.class.getResourceAsStream(birdFiles[birdIndex]))));
                }

            };
    ...
}

这篇关于如何在JavaFX中使用时间轴更改图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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