How to retrieve stage from JavaFX Application Class


Question

I am writing an application with 2 different BorderPanes, BorderPane A and BorderPane B. The application has 2 menuitems, such that, when clicked it HAS to show BorderPane A or BorderPane B.

This is the Application class, which has the stage I want to use

public class SampleApp extends Application {
private Stage primaryStage;

public static void main(final String[] args) {
    launch(args);
}    
@Override
public void start(final Stage stage)
        throws Exception {
    final AnnotationConfigApplicationContext context = new  AnnotationConfigApplicationContext(SampleAppFactory.class);
    final SpringFxmlLoader loader = new SpringFxmlLoader(context);      
    final Parent root = (Parent) loader.load("Main.fxml", Main.class);
    final Scene scene = new Scene(root, 600, 480, Color.ALICEBLUE);
    this.primaryStage = stage;
    scene.getStylesheets().add("fxmlapp.css");
    stage.setScene(scene);
    stage.show();
}
}

The Main.java Class has two BorderPanes, when the menuItem is chosen I want to show the borderpane on the Application.

Does someone knows how to show the Borderpane(set the Scene on Stage) from this method(showBorderPane)? I'd like to retrieve the Stage and set the scene with de borderpane:

public class Main extends BorderPane implements Initializable {

@FXML
private Verbinding verbindingContent; // BORDERPANE A
@FXML
private Beheer beheerContent;// BORDERPANE A
@FXML
private MenuBar menuContent;

@Override
public void initialize(final URL url, final ResourceBundle rb) {
    System.out.println(url);
    menuContent.setFocusTraversable(true);
}

@FXML
private void showBorderPane(final ActionEvent event) {
    final MenuItem menuItem = (MenuItem) event.getSource();
}


@FXML
private void handleCloseAction(final ActionEvent event) {
    System.exit(0);
}

}

my Main.xml

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.effect.*?>
<?import nl.mamaloe.tab.view.Main?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="nl.mamaloe.tab.view.Main">
<fx:define>     
    <fx:include source="scene/Beheer.fxml" fx:id="beheerContent" />
    <!-- fx:include source="Menu.fxml" fx:id="menuContent" / -->
</fx:define>
<top>
    <MenuBar fx:id="menuContent" onMouseClicked="#handleKeyInput">
        <menus>
            <Menu text="Systeem">
                <items>
                    <MenuItem text="Verbinding maken" onAction="#handleVerbindingAction"/>
                    <SeparatorMenuItem />
                    <MenuItem text="Afsluiten"  onAction="#handleCloseAction"/>
                </items>
            </Menu>

            <Menu text="TAB">
                <items>
                    <MenuItem text="Script toevoegen" onAction="#handleAboutAction"/>
                    <SeparatorMenuItem />
                    <MenuItem text="Script draaien" />                      
                </items>
            </Menu>
            <Menu text="About" onAction="#handleAboutAction">
                <items>
                    <MenuItem text="Op basis van wizard" />
                </items>
            </Menu>
        </menus>
    </MenuBar>
</top> 
<center>   <Label text="Add New Dock of Home" />

</center>

I've seen it is possible to do this from the start method of the application. But I'd like to implement it in the Main.java because of structure and I am using mainly FXML to declare the GUI.

1
3
5/29/2012 10:52:05 AM

Accepted Answer

When the "Main.fxml" file is loaded by FXMLLoader, a new BorderPane (defined in Main.fxml) is created. The loader also creates/initializes its controller class which is another BorderPane-derived class with its own instance. So there are two different instances of BorderPanes. Your design is a bit different from general approach though, to achieve your goal, I suggest to add a container into center in FXML file like this:

<center>
    <StackPane fx:id="pane">
        <children>
              <Label text="Add New Dock of Home" />
        </children>
    </StackPane>
</center>

You can change the StackPane with any pane/layout you want. Next make a link to it in the controller class:

@FXML
private StackPane pane;

and you should remove "extends BorderPane" because it is no sense anymore. Finally,

@FXML
private void showBorderPane(final ActionEvent event) {
    final MenuItem menuItem = (MenuItem) event.getSource();
    pane.getChildren().clear(); // Clear old content.
    switch (menuItem.getText()) {
        case "Borderpane A":
            pane.getChildren().add(borderPaneA);
            break;
        case "Borderpane B":
            pane.getChildren().add(borderPaneB);
            break;
       default:
            pane.getChildren().add(new Label("Add New Dock of Home"));
    }
}
1
5/29/2012 11:51:17 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon