2014-11-23 132 views
4

是否可以使用幻灯片效果切换场景?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); 
    } 
} 
+0

你需要一个幻灯片效果,或者你想知道它是否可能? – Elltz 2014-11-23 18:27:18

回答

5

不能应用的过渡两个场景之间,因为它是不可能在同一时间上一个阶段兼得。一个解决方案就是只有一个场景并管理里面的所有转换,就像@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

0

AFAIK这是不可能的。不要滑动场景,请尝试在一个场景中创建不同的布局,并在它们之间滑动。

+0

先生,这应该是一个评论或? – Elltz 2014-11-23 18:25:43

0

我建议看看Pagination控件。

它用动画切换其内容窗格。您可以自定义这一个以适应您的需求,或者查看其皮肤实现以了解如何执行动画。

4

A Stage可以包含一个且只有一个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); 
    } 
}