具有幻灯片效果的JavaFX切换场景

具有幻灯片效果的JavaFX切换场景,java,animation,javafx,Java,Animation,Javafx,是否可以使用幻灯片效果切换场景 当我调用stage实例上的setScene时,我需要这样做 它使用幻灯片效果更改场景。有可能吗 public class ManyScenes extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(final Stage prima

是否可以使用幻灯片效果切换场景

当我调用stage实例上的setScene时,我需要这样做 它使用幻灯片效果更改场景。有可能吗

public class ManyScenes extends Application {

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

    @Override
    public void start(final Stage primaryStage) {
        primaryStage.setTitle("Slide");

        Group root1 = new Group();
        Group root2 = new Group();

        Scene scene1 = new Scene(root1, 300, 250);
        Scene scene2 = new Scene(root2, 300, 250);

        Rectangle rectangle2 = new Rectangle(300, 250);
        rectangle2.setFill(Color.BLUE);
        root2.getChildren().add(rectangle2);

        Rectangle rectangle1 = new Rectangle(300, 250);
        rectangle1.setFill(Color.RED);
        root1.getChildren().add(rectangle1);



        primaryStage.setScene(scene1);
        primaryStage.show();

        // Here i  need a slide effect,
        // this method is called when a button is pressed.
        primaryStage.setScene(scene2);
    }
}

恐怕这不可能。与其滑动场景,不如尝试在一个场景内创建不同的布局,然后在它们之间滑动。

好吧,这是不可能的。与其滑动场景,不如尝试在一个场景内创建不同的布局并在它们之间滑动。

我建议您查看一下控件


它使用动画切换其内容窗格。您可以自定义此控件以满足您的需要,也可以查看其外观实现,了解如何制作动画。

我建议您查看一下控件


它使用动画切换其内容窗格。您可以根据需要自定义此场景,也可以查看其皮肤实现,了解如何制作动画。

a
Stage
可以包含一个且只有一个
场景
,每个
场景
都有一个且只有一个根。因此,您需要在单个场景的根中管理过渡

简单的例子:

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class SlidingViews extends Application {

    @Override
    public void start(Stage primaryStage) {
        Rectangle rectangle1 = new Rectangle(300, 250);
        rectangle1.setFill(Color.RED);

        Button nextView = new Button("Next");
        nextView.setPadding(new Insets(10));
        BorderPane view1 = new BorderPane(rectangle1, null, null, nextView, null);
        BorderPane.setAlignment(nextView, Pos.CENTER);

        Group view2 = new Group();
        Rectangle rectangle2 = new Rectangle(300, 250);
        rectangle2.setFill(Color.BLUE);
        view2.getChildren().add(rectangle2);

        StackPane root = new StackPane(view1);

        nextView.setOnAction(event -> {
            root.getChildren().add(view2);
            double width = root.getWidth();
            KeyFrame start = new KeyFrame(Duration.ZERO,
                    new KeyValue(view2.translateXProperty(), width),
                    new KeyValue(view1.translateXProperty(), 0));
            KeyFrame end = new KeyFrame(Duration.seconds(1),
                    new KeyValue(view2.translateXProperty(), 0),
                    new KeyValue(view1.translateXProperty(), -width));
            Timeline slide = new Timeline(start, end);
            slide.setOnFinished(e -> root.getChildren().remove(view1));
            slide.play();
        });

        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

一个
阶段
只能包含一个
场景
,每个
场景
都有一个且只有一个根。因此,您需要在单个场景的根中管理过渡

简单的例子:

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class SlidingViews extends Application {

    @Override
    public void start(Stage primaryStage) {
        Rectangle rectangle1 = new Rectangle(300, 250);
        rectangle1.setFill(Color.RED);

        Button nextView = new Button("Next");
        nextView.setPadding(new Insets(10));
        BorderPane view1 = new BorderPane(rectangle1, null, null, nextView, null);
        BorderPane.setAlignment(nextView, Pos.CENTER);

        Group view2 = new Group();
        Rectangle rectangle2 = new Rectangle(300, 250);
        rectangle2.setFill(Color.BLUE);
        view2.getChildren().add(rectangle2);

        StackPane root = new StackPane(view1);

        nextView.setOnAction(event -> {
            root.getChildren().add(view2);
            double width = root.getWidth();
            KeyFrame start = new KeyFrame(Duration.ZERO,
                    new KeyValue(view2.translateXProperty(), width),
                    new KeyValue(view1.translateXProperty(), 0));
            KeyFrame end = new KeyFrame(Duration.seconds(1),
                    new KeyValue(view2.translateXProperty(), 0),
                    new KeyValue(view1.translateXProperty(), -width));
            Timeline slide = new Timeline(start, end);
            slide.setOnFinished(e -> root.getChildren().remove(view1));
            slide.play();
        });

        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

不能在两个场景之间应用过渡,因为不可能在一个舞台上同时使用这两个场景。一种解决方案是只使用一个场景并管理内部的所有过渡,如@James_D answer

但您也可以模拟两个场景之间的过渡。为此,您可以使用两者的两个快照,在它们之间执行转换,最后只需设置新场景

这是一个非常基本的工作案例,您只需在新场景中单击,就可以再次前后移动:

@Override
public void start(Stage primaryStage) {
    Group root1 = new Group();
    Group root2 = new Group();

    Scene scene1 = new Scene(root1, 300, 250);
    Scene scene2 = new Scene(root2, 300, 250);

    Rectangle rectangle2 = new Rectangle(300, 250);
    rectangle2.setFill(Color.BLUE);
    root2.getChildren().add(rectangle2);

    Rectangle rectangle1 = new Rectangle(300, 250);
    rectangle1.setFill(Color.RED);
    root1.getChildren().add(rectangle1);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene1);
    primaryStage.show();

    rectangle1.setOnMouseClicked(e->{
        // Create snapshots with the last state of the scenes
        WritableImage wi = new WritableImage(300, 250);
        Image img1 = root1.snapshot(new SnapshotParameters(),wi);
        ImageView imgView1= new ImageView(img1);
        wi = new WritableImage(300, 250);
        Image img2 = root2.snapshot(new SnapshotParameters(),wi);
        ImageView imgView2= new ImageView(img2);
        // Create new pane with both images
        imgView1.setTranslateX(0);
        imgView2.setTranslateX(300);
        StackPane pane= new StackPane(imgView1,imgView2);
        pane.setPrefSize(300,250);
        // Replace root1 with new pane
        root1.getChildren().setAll(pane);
        // create transtition
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(imgView2.translateXProperty(), 0, Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(1), kv);
        timeline.getKeyFrames().add(kf);
        timeline.setOnFinished(t->{
            // remove pane and restore scene 1
            root1.getChildren().setAll(rectangle1);
            // set scene 2
            primaryStage.setScene(scene2);
        });
        timeline.play();
    });
    rectangle2.setOnMouseClicked(e->{
        // Create snapshots with the last state of the scenes
        WritableImage wi = new WritableImage(300, 250);
        Image img1 = root1.snapshot(new SnapshotParameters(),wi);
        ImageView imgView1= new ImageView(img1);
        wi = new WritableImage(300, 250);
        Image img2 = root2.snapshot(new SnapshotParameters(),wi);
        ImageView imgView2= new ImageView(img2);
        // Create new pane with both images
        imgView2.setTranslateX(0);
        imgView1.setTranslateX(300);
        StackPane pane= new StackPane(imgView2,imgView1);
        pane.setPrefSize(300,250);
        // Replace root2 with new pane
        root2.getChildren().setAll(pane);
        // create transtition
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(imgView1.translateXProperty(), 0, Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(1), kv);
        timeline.getKeyFrames().add(kf);
        timeline.setOnFinished(t->{
            // remove pane and restore scene 2
            root2.getChildren().setAll(rectangle2);
            // set scene 1
            primaryStage.setScene(scene1);
        });
        timeline.play();
    });

}

有关更复杂的效果,请查看。

您不能在两个场景之间应用过渡,因为不可能在一个舞台上同时使用两个场景。一种解决方案是只使用一个场景并管理内部的所有过渡,如@James_D answer

但您也可以模拟两个场景之间的过渡。为此,您可以使用两者的两个快照,在它们之间执行转换,最后只需设置新场景

这是一个非常基本的工作案例,您只需在新场景中单击,就可以再次前后移动:

@Override
public void start(Stage primaryStage) {
    Group root1 = new Group();
    Group root2 = new Group();

    Scene scene1 = new Scene(root1, 300, 250);
    Scene scene2 = new Scene(root2, 300, 250);

    Rectangle rectangle2 = new Rectangle(300, 250);
    rectangle2.setFill(Color.BLUE);
    root2.getChildren().add(rectangle2);

    Rectangle rectangle1 = new Rectangle(300, 250);
    rectangle1.setFill(Color.RED);
    root1.getChildren().add(rectangle1);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene1);
    primaryStage.show();

    rectangle1.setOnMouseClicked(e->{
        // Create snapshots with the last state of the scenes
        WritableImage wi = new WritableImage(300, 250);
        Image img1 = root1.snapshot(new SnapshotParameters(),wi);
        ImageView imgView1= new ImageView(img1);
        wi = new WritableImage(300, 250);
        Image img2 = root2.snapshot(new SnapshotParameters(),wi);
        ImageView imgView2= new ImageView(img2);
        // Create new pane with both images
        imgView1.setTranslateX(0);
        imgView2.setTranslateX(300);
        StackPane pane= new StackPane(imgView1,imgView2);
        pane.setPrefSize(300,250);
        // Replace root1 with new pane
        root1.getChildren().setAll(pane);
        // create transtition
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(imgView2.translateXProperty(), 0, Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(1), kv);
        timeline.getKeyFrames().add(kf);
        timeline.setOnFinished(t->{
            // remove pane and restore scene 1
            root1.getChildren().setAll(rectangle1);
            // set scene 2
            primaryStage.setScene(scene2);
        });
        timeline.play();
    });
    rectangle2.setOnMouseClicked(e->{
        // Create snapshots with the last state of the scenes
        WritableImage wi = new WritableImage(300, 250);
        Image img1 = root1.snapshot(new SnapshotParameters(),wi);
        ImageView imgView1= new ImageView(img1);
        wi = new WritableImage(300, 250);
        Image img2 = root2.snapshot(new SnapshotParameters(),wi);
        ImageView imgView2= new ImageView(img2);
        // Create new pane with both images
        imgView2.setTranslateX(0);
        imgView1.setTranslateX(300);
        StackPane pane= new StackPane(imgView2,imgView1);
        pane.setPrefSize(300,250);
        // Replace root2 with new pane
        root2.getChildren().setAll(pane);
        // create transtition
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(imgView1.translateXProperty(), 0, Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(1), kv);
        timeline.getKeyFrames().add(kf);
        timeline.setOnFinished(t->{
            // remove pane and restore scene 2
            root2.getChildren().setAll(rectangle2);
            // set scene 1
            primaryStage.setScene(scene1);
        });
        timeline.play();
    });

}

要获得更复杂的效果,请查看。

先生,这应该是一条评论,还是?先生,这应该是一条评论,还是?您需要幻灯片效果,或者您想知道它是否可能?您需要幻灯片效果,或者您想知道它是否可能?