Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JavaFX中创建连续的TranslateTransition_Java_Animation_Javafx_Delay_Transitions - Fatal编程技术网

如何在JavaFX中创建连续的TranslateTransition

如何在JavaFX中创建连续的TranslateTransition,java,animation,javafx,delay,transitions,Java,Animation,Javafx,Delay,Transitions,我正在使用JavaFX创建一个Java应用程序,它能够将TranslateTransition应用到一个通用节点并不断地调用它。 我从此url检索到一个简单的右箭头: 并使用它创建要转换的节点。 这是我的AnimatedNode类: package application.model.utils.addon; import javafx.animation.TranslateTransition; import javafx.scene.Node; import javafx.util.Dur

我正在使用JavaFX创建一个Java应用程序,它能够将TranslateTransition应用到一个通用节点并不断地调用它。 我从此url检索到一个简单的右箭头: 并使用它创建要转换的节点。 这是我的AnimatedNode类:

package application.model.utils.addon;

import javafx.animation.TranslateTransition;
import javafx.scene.Node;
import javafx.util.Duration;

public class AnimatedNode {

    private Node node;
    private double positionY;
    private TranslateTransition translateTransition;
    private boolean animated;

    private int reverse = 1;

    public AnimatedNode(Node node, double animationTime) {
        setPositionY(0.0);
        setNode(node);
        setTranslateTransition(animationTime);
    }

    public void play() {
        if(translateTransition != null && !isAnimated()) {

            setAnimated(true);

            new Thread() {
                @Override
                public void run() {
                    while(isAnimated()) {
                        translateTransition.setToY(positionY + 50 * reverse);
                        translateTransition.play();

                        reverse = -reverse;
                        setPositionY(translateTransition.getToY());
                    }
                }
            }.start();
        }
    }

    public void stop() {
        setAnimated(false);
    }

    public Node getNode() {
        return node;
    }

    private void setNode(Node node) {
        this.node = node;
    }

    public TranslateTransition getTranslateTransition() {
        return translateTransition;
    }

    private void setTranslateTransition(double animationTime) {
        translateTransition = new TranslateTransition();

        if(node != null) {
            translateTransition.setDuration(Duration.seconds(animationTime));
            translateTransition.setNode(node);
        }
    }

    public double getPositionY() {
        return positionY;
    }

    private void setPositionY(double positionY) {
        this.positionY = positionY;
    }

    public boolean isAnimated() {
        return animated;
    }

    private void setAnimated(boolean animated) {
        this.animated = animated;
    }
}
这是应用程序类

package test;

import application.model.utils.addon.AnimatedNode;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Test extends Application {

    private final String TITLE = "Test application";
    private final double WIDTH = 600;
    private final double HEIGHT = 400;
    private final String ARROW_PATH = "file:resources/png/arrow.png";

    private BorderPane rootPane;

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle(TITLE);

        rootPane = new BorderPane();
        rootPane.setPrefSize(WIDTH, HEIGHT);

        Image image = new Image(ARROW_PATH);
        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(WIDTH);
        imageView.setFitHeight(HEIGHT);
        imageView.setPreserveRatio(true);
        AnimatedNode animatedNode = new AnimatedNode(imageView, 0.7);

        Pane pane = new Pane();
        pane.getChildren().add(animatedNode.getNode());

        pane.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent arg0) {
                if(arg0.getButton().equals(MouseButton.PRIMARY))
                    animatedNode.play();

                if(arg0.getButton().equals(MouseButton.SECONDARY))
                    animatedNode.stop();
            }
        });

        rootPane.setCenter(pane);
        Scene scene = new Scene(rootPane, WIDTH, HEIGHT);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
封装测试;
导入application.model.utils.addon.AnimatedNode;
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.input.MouseButton;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.Pane;
导入javafx.stage.stage;
公共类测试扩展了应用程序{
私有最终字符串TITLE=“测试应用程序”;
专用最终双宽度=600;
私人最终双倍高度=400;
私有最终字符串ARROW\u PATH=“file:resources/png/ARROW.png”;
私有边界窗格根窗格;
@凌驾
公共无效开始(阶段primaryStage){
初级阶段。设置标题(标题);
rootPane=newborderpane();
rootPane.setPrefSize(宽度、高度);
图像=新图像(箭头\路径);
ImageView ImageView=新的ImageView(图像);
imageView.setFitWidth(宽度);
imageView.setFitHeight(高度);
imageView.setPreserveRatio(真);
AnimatedNode AnimatedNode=新的AnimatedNode(imageView,0.7);
窗格=新窗格();
pane.getChildren().add(animatedNode.getNode());
setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent arg0){
if(arg0.getButton().equals(MouseButton.PRIMARY))
animatedNode.play();
if(arg0.getButton().equals(MouseButton.SECONDARY))
animatedNode.stop();
}
});
根窗格。设置中心(窗格);
场景=新场景(根窗格、宽度、高度);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
将节点添加到通用窗格中;窗格上有一个鼠标听筒。我可以使用鼠标的主按钮启动TranslateTransition,然后使用第二个按钮停止它。 我在AnimatedNode的play()方法中使用了一个线程,但在转换过程中仍然有一个连续的延迟。 这是执行转换的最佳方式吗?我可以改进我的代码吗

非常感谢您的支持。

示例

这是一个简化的示例,演示了通过鼠标左键和右键单击开始和停止的连续动画

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.*;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BouncingCat extends Application {    
    private static final double WIDTH = 100;
    private static final double HEIGHT = 100;
    private final String ARROW_PATH =
            "http://icons.iconarchive.com/icons/iconka/meow-2/64/cat-rascal-icon.png";
            // image source: http://www.iconka.com

    @Override
    public void start(Stage stage) {
        Image image = new Image(ARROW_PATH);
        ImageView imageView = new ImageView(image);
        TranslateTransition animation = new TranslateTransition(
                Duration.seconds(0.7), imageView
        );
        animation.setCycleCount(Animation.INDEFINITE);
        animation.setFromY(0);
        animation.setToY(50);
        animation.setAutoReverse(true);

        Pane pane = new Pane(imageView);
        Scene scene = new Scene(pane, WIDTH, HEIGHT);

        scene.setOnMouseClicked(e -> {
            switch (e.getButton()) {
                case PRIMARY:
                    animation.play();
                    break;

                case SECONDARY:
                    animation.pause();
                    break;
            }
        });

        stage.setScene(scene);
        stage.show();
    }

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

在进行转换时,不需要线程。JavaFX将自动渲染更新的转换帧

我不建议跟踪类中的属性,因为在您使用的底层工具中已经表示了相同的值

例如:

  • 替换
    int reverse=1带有或(或-1)
  • 将动画的替换为
  • 设置转换的位置,而不是双位置
我不建议调用您的类AnimatedNode,除非它是扩展节点,否则它会令人困惑,而应该调用类似AnimationControl的东西

import javafx.animation.TranslateTransition;
import javafx.scene.Node;
import javafx.util.Duration;

public class AnimationControl {
    private final TranslateTransition translateTransition;

    public AnimationControl(Duration duration, Node node) {
        translateTransition = new TranslateTransition(duration, node);
    }

    public TranslateTransition getTranslateTransition() {
        return translateTransition;
    }
}
您只需要在AnimationControl中封装节点和过渡,而不需要封装其他字段,除非您需要进一步的功能,这些功能在您的问题中不明显,并且节点或过渡尚未提供。如果您有额外的功能,那么您可以增强上面的AnimationControl类来添加它


公开节点和平移转换就足够了,就好像用户想要管理动画一样,比如启动和停止动画,那么用户就可以从AnimationControl类获取动画。根据您的使用情况,整个AnimationControl类可能是不必要的,因为您可能不需要它提供的封装,而是更愿意直接使用节点和转换(如示例中演示的)。

非常感谢您的帮助!如您所见,我不知道转换类的方法,所以我试图自己实现一个无限循环。你的方法显然是最好的。