I've realised only through clearing up code that I thought I could clear up and had cleared from some of my Controller classes where my issue is. To word my question better and provide more clarity to the concept of prioritisation I'll give a brief explanation followed by some code. Imagine an interface with a side of the screen being consistent and permanent to the interface where you have Buttons for menu-ing where you essentially move between tabs changing the rest of the Stage passing fxml files to the Pane associated.
Reading examples and questions I understood this to be viable and using the framework from this link https://gist.github.com/jewelsea/6460130 seeing a header remain consistent while switching Scene between vista1.fxml and vista2.fxml, my understanding was that if the Header remains from main.fxml as part of the scene that the Stage is therefore using either both main.fxml and vista1.fxml or main.fxml and vista2.fxml concurrently and thus both associated controllers exist and will have access to corresponding methods according to the Pane interacted with.
That is clearly not the case though and the consistent Pane in this case main.fxml does not have its controller since when the other is loaded and creates its controller it replaces or clears the other controller in some form or another I now presume is the case. I thought I could avoid code duplication by using separate Panes with the consistency of the menu bar but also being able to use its buttons.
Some code as an example: Main.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception{
stage.setTitle("Vista Viewer");
stage.setScene(createScene(loadMainPane()));
stage.show();
}
private Pane loadMainPane() throws IOException {
FXMLLoader loader = new FXMLLoader();
Pane mainPane = (Pane) loader.load(getClass().getResourceAsStream(
VistaNavigator.MAIN));
MainController mainController = loader.getController();
VistaNavigator.setMainController(mainController);
VistaNavigator.loadVista(VistaNavigator.VISTA_1);
return mainPane;
}
private Scene createScene(Pane mainPane) {
Scene scene = new Scene(mainPane);
return scene;
}
public static void main(String[] args) {
launch(args);
}
}
VistaNavigator.java
package sample;
import javafx.fxml.FXMLLoader;
import java.io.IOException;
public class VistaNavigator {
public static final String MAIN = "main.fxml";
public static final String VISTA_1 = "vista1.fxml";
public static final String VISTA_2 = "vista2.fxml";
public static final String OTHER_MENU_OPTION = "otherMenu.fxml";
private static MainController mainController;
public static void setMainController(MainController mainController) {
VistaNavigator.mainController = mainController;
}
public static void loadVista(String fxml) {
try {
mainController.setVista(
FXMLLoader.load(
VistaNavigator.class.getResource(
fxml
)
)
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainController.java
package sample;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.layout.StackPane;
public class MainController {
@FXML
private StackPane vistaHolder;
public void setVista(Node node) {
vistaHolder.getChildren().setAll(node);
}
public void homebtn() throws Exception{
VistaNavigator.loadVista(VistaNavigator.VISTA_1);
}
public void otherMenuOption() throws Exception{
VistaNavigator.loadVista(VistaNavigator.OTHER_MENU_OPTION);
}
}
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="200.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.MainController">
<children>
<VBox prefWidth="155.0">
<children>
<Label fx:id="headerLabel" maxWidth="120.0" text="Header" />
</children>
</VBox>
<Pane layoutY="40.0" prefHeight="200.0" prefWidth="120.0" style="-fx-background-color: #091D34;">
<children>
<Button fx:id="button1" layoutY="60.0" mnemonicParsing="false" onAction="#homebtn" prefHeight="44.0" prefWidth="120.0" style="-fx-background-color: #133863;" text="Home" textFill="WHITE">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
<Button fx:id="button2" layoutY="110.0" mnemonicParsing="false" onAction="#otherMenuOption" prefHeight="44.0" prefWidth="120.0" style="-fx-background-color: #133863;" text="OtherMenuOption" textFill="WHITE">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
</children>
</Pane>
<StackPane fx:id="vistaHolder" VBox.vgrow="ALWAYS" />
</children>
</AnchorPane>
otherMenu.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane fx:id="otherMenuOption" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.Vista1Controller">
<children>
<Label fx:id="label" layoutX="135.0" layoutY="57.0" maxWidth="120.0" text="other program stuff" VBox.vgrow="NEVER" />
</children>
</StackPane>
Vista1Controller.java
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
public class Vista1Controller {
@FXML
void nextPane(ActionEvent event) {
VistaNavigator.loadVista(VistaNavigator.VISTA_2);
}
}
vista1.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.Vista1Controller" prefHeight="400.0" prefWidth="600.0">
<children>
<Pane fx:id="Vista1" layoutX="155.0" layoutY="-1.0" prefHeight="430.0" prefWidth="574.0" style="-fx-background-color: transparent">
<Button fx:id="btn" layoutX="135.0" layoutY="57.0" mnemonicParsing="false" onAction="#nextPane" prefHeight="149.0" prefWidth="318.0" style="-fx-background-color: #133863;" text="Open Vista2" textFill="#ffffff">
<font>
<Font name="Britannic Bold" size="20.0" />
</font>
</Button>
</Pane>
</children>
</AnchorPane>
Vista2Controller.java
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
public class Vista2Controller {
@FXML
void previousPane(ActionEvent event) {
VistaNavigator.loadVista(VistaNavigator.VISTA_1);
}
}
vista2.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.Vista2Controller" prefHeight="400.0" prefWidth="600.0">
<children>
<Pane fx:id="Vista2" layoutX="155.0" layoutY="-1.0" prefHeight="430.0" prefWidth="574.0" style="-fx-background-color: transparent">
<Button fx:id="btn" layoutX="135.0" layoutY="57.0" mnemonicParsing="false" onAction="#previousPane" prefHeight="149.0" prefWidth="318.0" style="-fx-background-color: #133863;" text="Open Vista1" textFill="#ffffff">
<font>
<Font name="Britannic Bold" size="20.0" />
</font>
</Button>
</Pane>
</children>
</AnchorPane>
Is there a good way to maintain this design and prevent code duplication within the specific controllers and would it be through inheritance or passing parameters, I'm not sure what this is comparable to nor whether it's possible?