我有一个扩展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());
}
}
}
答案 0 :(得分:8)
推荐方法
不要为此使用多个阶段,而是使用单个阶段和多个场景或分层窗格。
示例参考
背景
阅读有关JavaFX背后的theater metaphor的讨论,以帮助理解Stage和Scene之间的区别以及为什么您希望改变应用程序内外的场景而不是阶段。
简单样本
我根据您的应用程序描述创建了一个简单的示例,它只是在主场景和选项场景之间来回切换。当您在场景之间来回切换时,您可以看到主场景和选项场景都保留了场景状态。
对于示例,只有一个阶段引用,它以start
方法传递给应用程序,并且阶段引用保存在应用程序中。应用程序为主屏幕创建场景,为选项屏幕创建另一个场景,保存两个场景引用,根据需要使用stage.setScene在这些引用之间来回切换当前显示的场景。
该演示非常简单易于理解,并且不会保留任何使用的数据或使用MVC样式架构或FXML,这可能在更逼真的演示中完成。
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);
}
}