Вот контроллер, который заменяет себя из FXML-файла.
Это просто и имеет только одну кнопку, которая запускает замену, но это делает.
Stage, Scene и Controller хранятся как статические переменные, чтобы хранить все в одном файле. Вы можете хранить их где угодно.
public class RootReplacingItselfController implements Initializable {
public static RootReplacingItselfController controller = null;
public static Stage stage = null;
public static Scene scene = null;
public final static String filename = "/fxml/RootReplacingItself.fxml";
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void replaceme(ActionEvent event) {
try {
//open an additional modal Dialog
FXMLLoader dialogloader = new FXMLLoader(FXMLLoader.class.getResource(filename));
Stage dialog = new Stage();
dialog.setScene(new Scene(dialogloader.load()));
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(stage);
dialog.showAndWait();
//When the dialog is done replace myself:
FXMLLoader loader = new FXMLLoader(FXMLLoader.class.getResource(filename));
Parent node = loader.load();
controller= loader.getController();
scene.setRoot(node);
} catch (IOException ex) {}
}
public static RootReplacingItselfController create(){
try {
FXMLLoader loader = new FXMLLoader(FXMLLoader.class.getResource(filename));
Parent node = loader.load();
controller= loader.getController();
scene = new Scene(node);
stage = new Stage();
stage.setScene(scene);
stage.show();
return controller;
} catch (IOException ex) {}
return controller;
}
}
И FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="151.0" prefWidth="232.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="fxControls.RootReplacingItselfController">
<children>
<Button layoutX="76.0" layoutY="76.0" mnemonicParsing="false" onAction="#replaceme" text="replaceme" />
</children>
</AnchorPane>
Я отредактировал его, чтобы кнопка дополнительно открывала модальный дочерний диалог. Теперь этот диалог снова создается из того же fxml.
В этом модальном диалоговом окне вы можете снова нажать кнопку замены и открыть другое модальное диалоговое окно, а затем снова в этом третьем и т. Д.
Каждый раз, когда модальное диалоговое окно закрывается (диалоговое окно готово), корневой контроллер заменяется. Для всех детей, которые были созданы.
Так что теперь у вас также есть этот модальный диалог. Как только диалоговое окно закрыто, рут заменяется (и это всегда корень). И, конечно же, вы можете использовать другой FXM для диалога.
FWIW: Лично я пока не могу представить себе реальный проект, в котором я бы выбрал такой подход, поскольку он очень вероятно вызывает головную боль, когда возникает взаимодействие с другими частями приложения. Но это не мне решать.