可以用幻灯片效果切换场景吗?
当我在舞台实例上调用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);
}
}
答案 0 :(得分: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();
});
}
对于更复杂的效果,请查看this。
答案 1 :(得分:4)
Stage
可以包含一个且只有一个Scene
,每个Scene
只有一个根。{1}}。因此,您需要在单个场景的根目录内管理转换。
简单示例:
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);
}
}
答案 2 :(得分:0)
AFAIK这是不可能的。不是滑动场景,而是尝试在一个场景中创建不同的布局并在它们之间滑动。
答案 3 :(得分:0)
我建议您查看Pagination控件。
它用动画切换其内容窗格。您可以自定义此选项以满足您的需求,也可以查看其外观实现,以了解如何进行动画制作。