2014-11-23 93 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); 
    } 
}