具有幻灯片效果的JavaFX Switch场景

Ema*_*max 5 java animation javafx

可以用幻灯片效果切换场景吗?

我希望当我在舞台实例上调用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*eda 7

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

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

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

@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();
    });

}
Run Code Online (Sandbox Code Playgroud)

对于更复杂的特效来看看这个.


Jam*_*s_D 5

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

简单的例子:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)