JavaFX - 每个阶段的独特场景

时间:2013-03-19 17:40:17

标签: javafx instance stage

我有一个扩展Application的类并调用主要阶段。这个主要阶段有一个Next Button,它将调用另一个阶段(选项阶段)。选项阶段有一个上一个按钮。 我想获得主要阶段的实例,处于用户单击“下一步”按钮之前的状态,例如:带有输入数据的文本字段或带有所选项目的组合框。 我怎么能这样做?

主要课程:

public class MainClass extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        final FXMLLoader loader = new FXMLLoader(getClass().getResource("interfaceOne.fxml"));
        final Parent root = (Parent)loader.load();
        final MyController controller = loader.<MyController>getController();

        primaryStage.initStyle(StageStyle.TRANSPARENT);
        primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("icon.png")));

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        Platform.setImplicitExit(false);

        controller.setStage(primaryStage);
        primaryStage.show();        
    }

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

}

myController的:

public class MyController{

    // Some declarations ...

    Stage stage = null;

    public void setStage(Stage stage) {
       this.stage = stage;
    }

    // Next button's action
    @FXML
    public void handleNextAction(ActionEvent event) {

        try {  

            Parent root = FXMLLoader.load(getClass().getResource("optionInterface.fxml"));

            stage.initStyle(StageStyle.TRANSPARENT);
            stage.getIcons().add(new Image(getClass().getResourceAsStream("icon.png")));
            stage.setScene(new Scene(root));
            stage.show();

            // Hide the current screen
            ((Node)(event.getSource())).getScene().getWindow().hide();

        } catch (Exception exc) {
            System.out.println("Error: " + exc.getMessage());
        }
    }
}

选项控制器:

public class OptionsController implements Initializable {

    public void handlePreviousAction(ActionEvent event) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("interfaceOne.fxml"));;
            MyController controller = MyController.getInstance();

            stage.initStyle(StageStyle.TRANSPARENT);
            stage.getIcons().add(new Image(getClass().getResourceAsStream("icon.png")));
            stage.setScene(new Scene(root));

            controller.setStage(stage);
            controller.isLocationLoaded(false);
            stage.show();

            // Hide the current screen
            ((Node)(event.getSource())).getScene().getWindow().hide();

        } catch (IOException exc) {
            System.out.println("Error: " + exc.getMessage());

        }
    }
}

1 个答案:

答案 0 :(得分:8)

推荐方法

不要为此使用多个阶段,而是使用单个阶段和多个场景或分层窗格。

示例参考

  1. Angela Caicedo's sophisticated Scene switching tutorial
  2. A wizard style configuration
  3. 背景

    阅读有关JavaFX背后的theater metaphor的讨论,以帮助理解StageScene之间的区别以及为什么您希望改变应用程序内外的场景而不是阶段。

    简单样本

    我根据您的应用程序描述创建了一个简单的示例,它只是在主场景和选项场景之间来回切换。当您在场景之间来回切换时,您可以看到主场景和选项场景都保留了场景状态。

    对于示例,只有一个阶段引用,它以start方法传递给应用程序,并且阶段引用保存在应用程序中。应用程序为主屏幕创建场景,为选项屏幕创建另一个场景,保存两个场景引用,根据需要使用stage.setScene在这些引用之间来回切换当前显示的场景。

    该演示非常简单易于理解,并且不会保留任何使用的数据或使用MVC样式架构或FXML,这可能在更逼真的演示中完成。

    reservation options

    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.event.*;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    
    public class RoomReservationNavigator extends Application {
      public static void main(String[] args) { Application.launch(args); }
    
      private Scene mainScene;
      private Scene optionsScene;
      private Stage stage;
    
      @Override public void start(Stage stage) {
        this.stage = stage;
        mainScene    = createMainScene();
        optionsScene = createOptionsScene();
    
        stage.setScene(mainScene);
        stage.show();
      }
    
      private Scene createMainScene() {
        VBox layout = new VBox(10);
        layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
        layout.getChildren().setAll(
          LabelBuilder.create()
            .text("Room Reservation System")
            .style("-fx-font-weight: bold;") 
            .build(),
          HBoxBuilder.create()
            .spacing(5)
            .children(
              new Label("First Name:"),
              new TextField("Peter")
             )
            .build(),
          HBoxBuilder.create()
            .spacing(5)
            .children(
              new Label("Last Name:"),
              new TextField("Parker")
             )
            .build(),
          new Label("Property:"),
          ChoiceBoxBuilder.<String>create()
            .items(FXCollections.observableArrayList(
              "The Waldorf-Astoria", 
              "The Plaza", 
              "The Algonquin Hotel"
            ))
            .build(),
          ButtonBuilder.create()
            .text("Reservation Options  >>")
            .onAction(new EventHandler<ActionEvent>() {
              @Override public void handle(ActionEvent t) {
                stage.setScene(optionsScene);
              }
            })
            .build(),
          ButtonBuilder.create()
            .text("Reserve")
            .defaultButton(true)
            .onAction(new EventHandler<ActionEvent>() {
              @Override public void handle(ActionEvent t) {
                stage.hide();
              }
            })
            .build()
        );
    
        return new Scene(layout);
      }
    
      private Scene createOptionsScene() {
        VBox layout = new VBox(10);
        layout.setStyle("-fx-background-color: azure; -fx-padding: 10;");
        layout.getChildren().setAll(
          new CheckBox("Breakfast"),
          new Label("Paper:"),
          ChoiceBoxBuilder.<String>create()
            .items(FXCollections.observableArrayList(
              "New York Times", 
              "Wall Street Journal", 
              "The Daily Bugle"
            ))
            .build(),
          ButtonBuilder.create()
            .text("Confirm Options")
            .defaultButton(true)
            .onAction(new EventHandler<ActionEvent>() {
              @Override public void handle(ActionEvent t) {
                stage.setScene(mainScene);
              }
            })
            .build()
        );
    
        return new Scene(layout);
      }
    }