У меня есть класс, который расширяет Application и вызывает первичный этап. На этом первичном этапе есть кнопка «Далее», которая вызывает другой этап (этап опций). На этапе параметров есть кнопка «Назад». Я хотел бы получить экземпляр основного этапа в том состоянии, в котором он был до того, как пользователь нажал кнопку «Далее», например: текстовое поле с входными данными или поле со списком с выбранным элементом. Как я могу это сделать?

Основной класс:

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

        }
    }
}
0
Leonardo 19 Мар 2013 в 21:40
Отправьте код, который компилируется и включает fxml, если вы используете fxml.
 – 
jewelsea
20 Мар 2013 в 01:03

1 ответ

Лучший ответ

Рекомендуемый подход

Не используйте для этого несколько этапов, вместо этого используйте один этап и несколько сцен или многослойных панелей.

Образцы ссылок

  1. сложное руководство Анджелы Кайседо по переключению сцен.
  2. Конфигурация стиля мастера.

< EM> Фон

Прочтите обсуждение метафора театра за JavaFX, чтобы помочь понять разницу между Stage и Scene и почему вы, вероятно, захотите менять сцены внутри и вне вашего приложения, а не стадии.

Простой образец

Я создал простой образец на основе описания вашего приложения, который просто переключается между основной сценой и сценой с параметрами. Когда вы переключаетесь между сценами, вы можете видеть, что состояние сцены сохраняется как для основной сцены, так и для сцены параметров.

В примере есть только одна ссылка на этап, которая передается приложению в его методе 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);
  }
}
8
Community 23 Май 2017 в 15:07
Извините, я новичок в использовании JavaFX и не понял. Например, я добавил код.
 – 
Leonardo
19 Мар 2013 в 22:55
Ладно, я понял! Итак, согласно моему коду, когда я нажимаю кнопку «Назад» в сцене «Параметры», мне нужно будет показать сцену InterfaceOne. Могу ли я предположить, что эта сцена будет "одиночной"? Как я могу это сделать?
 – 
Leonardo
20 Мар 2013 в 01:35
Я добавил более простой пример кода, чем исходный пример мастера, возможно, это может вам помочь.
 – 
jewelsea
20 Мар 2013 в 02:49
Я понял! Таким образом, основной класс, расширяющий Application, будет управлять каждой сценой. Эти ссылки и ваш образец помогут! Большое спасибо!
 – 
Leonardo
20 Мар 2013 в 18:36