Enrico Sombini
Enrico Sombini

Reputation: 31

How to change Stage settings in a JavaFX program using fxml controllers

I have an application I am working on with a teammate, but we both are not sure how to change our Scene's title and parameters from inside our fxml controllers. This is the solution I tried, but it doesn't seem to work, as it says that Cannot invoke "javafx.stage.Stage.setMinHeight(double)" because "primaryStage" is null when i try to open the periodic table.

PeriodicTableFXMLController:

    public class PeriodicTableFXMLController {
    private final static Logger logger = LoggerFactory.getLogger(GasInABottleFXMLController.class);
    
    @FXML
    private Button backButton;

    @FXML
    private AnchorPane root;
    
    public void initialize() {
        logger.info("Initializing PeriodicTableFXMLController...");
        
        backButton.setOnMousePressed(event -> {
            MainApp.switchScene(MainApp.MAINAPP_LAYOUT, new MainAppFXMLController());
            logger.info("Loaded the primary scene...");
        });
        
        Scene scene = root.getScene();
        setStageSettings();
    }
    
    public void setStageSettings() {
        Stage primaryStage = MainApp.getStage();
        primaryStage.setMinHeight(963);
        primaryStage.setMinWidth(1419);
    }
}

MainApp:

public class MainApp extends Application {

    private final static Logger logger = LoggerFactory.getLogger(MainApp.class);
    public static Scene scene;
    public static final String MAINAPP_LAYOUT = "MainApp_layout";
    public static final String FORCES_UNLEASHED_LAYOUT =    "ForcesUnleashed_layout";
    public static final String SLIPPERY_SLIDE_LAYOUT ="SlipperySlide_layout";
    public static final String ATOM_BUILDER_LAYOUT = "AtomBuilder_layout";
    public static final String GAS_IN_A_BOTTLE_LAYOUT = "GasInABottle_layout";
    public static final String PERIODIC_TABLE_LAYOUT = "PeriodicTable_layout";
    public static final DecimalFormat format = new DecimalFormat("0.00");
    
    public static Stage primaryStage;
    @Override
    public void start(Stage primaryStage) {
        try {
            logger.info("Bootstrapping the application...");
            //-- 1) Load the scene graph from the specified FXML file and 
            // associate it with its FXML controller.
            Parent root = loadFXML(MAINAPP_LAYOUT, new MainAppFXMLController());
            //-- 2) Create and set the scene to the stage.
            scene = new Scene(root, 800, 800);
            primaryStage.setScene(scene);
            primaryStage.sizeToScene();
            // We just need to bring the main window to front.
            primaryStage.setAlwaysOnTop(true);
            primaryStage.show();
            primaryStage.setAlwaysOnTop(false);
            
            
        } catch (IOException ex) {
            logger.error(ex.getMessage(), ex);
        }
    }

    /**
     *
     * @param event
     * @param fxmlName
     */
    /**
     * Changes the primary stage's current scene.
     *
     * @param fxmlFile The name of the FXML file to be loaded.
     * @param fxmlController An instance of the FXML controller to be associated
     * with the loaded FXML scene graph.
     */
    public static void switchScene(String fxmlFile, Object fxmlController) {
        try {
            scene.setRoot(loadFXML(fxmlFile, fxmlController));
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Loads a scene graph from an FXML file.
     *
     * @param fxmlFile The name of the FXML file to be loaded.
     * @param fxmlController An instance of the FXML controller to be associated
     * with the loaded FXML scene graph.
     * @return The root node of the loaded scene graph.
     * @throws IOException
     */
    public static Parent loadFXML(String fxmlFile, Object fxmlController) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(MainApp.class.getResource("/fxml/" + fxmlFile + ".fxml"));
        fxmlLoader.setController(fxmlController);
        return fxmlLoader.load();
    }

    public static Scene getScene() {
        return scene;
    }
    
    public static Stage getStage() {
        return primaryStage;
    }
    

    public static void main(String[] args) {
        launch(args);
    }

    public static class decfor {

        public decfor() {
        }
    }
}

And MainAppFXMLController:

public class MainAppFXMLController {

    private final static Logger logger = LoggerFactory.getLogger(MainAppFXMLController.class);
    @FXML
    private Button btnAtomWizard, btnForcesUnleashed, btnPeriodicTable, btnGasInABottle, btnSlipperySlide, btnBack;
    @FXML private Button btnStart, btnAQuit2, btnAbout;
    @FXML private HBox hbMenu;
    @FXML private VBox vbMenu;
    //private Image = new Image("\\..\\..\\..\\Resources\\pictures\\somkodyn_wallpaper.png");
    //private Image somkodynBackground = new Image("file:somkodyn/pictures/somkodyn_wallpaper.png");
    @FXML private BorderPane bpBackdrop;
    @FXML private ImageView imgMenu;
    @FXML private TextArea taAbout;
    @FXML
    public void initialize() {
        
        //btnForcesUnleashed.setBackground(new Background(bgI));
        logger.info("Initializing MainAppController...");
        vbMenu.setAlignment(Pos.CENTER);
        btnAbout.setOnAction(e->{
            if(taAbout.isVisible()){
                taAbout.setVisible(false);
            }else{
                taAbout.setVisible(true);
            }
            
        });
        btnStart.setOnAction(e->{
            btnBack.setVisible(true);
            hbMenu.setVisible(true);
            vbMenu.setVisible(false);
            imgMenu.setVisible(true);
            taAbout.setVisible(false);
        });
        btnBack.setOnAction(e->{
            btnBack.setVisible(false);
            hbMenu.setVisible(false);
            vbMenu.setVisible(true);
            imgMenu.setVisible(false);
        });
        btnAtomWizard.setOnAction(this::launchAtomWizard);
        btnForcesUnleashed.setOnAction(this::launchForcesUnleashed);
        btnPeriodicTable.setOnAction(this::launchPeriodicTable);
        btnGasInABottle.setOnAction(this::launchGasInABottle);
        btnSlipperySlide.setOnAction(this::launchSlipperySlide);
        
    }
    @FXML
    private void quit(){
        System.exit(0);
    }
    
    private void launchAtomWizard(Event e) {
        MainApp.switchScene(MainApp.ATOM_BUILDER_LAYOUT, new AtomBuilderFXMLController());
        logger.info("Launching  Atom wizard...");
       
    }
    
     private void launchGasInABottle(Event e) {
        MainApp.switchScene(MainApp.GAS_IN_A_BOTTLE_LAYOUT, new GasInABottleFXMLController());
        logger.info("Launching  GasInABottle...");
    }


    private void launchForcesUnleashed(Event e) {
        logger.info("Launching  forces...");
        MainApp.switchScene(MainApp.FORCES_UNLEASHED_LAYOUT, new ForcesUnleashedFXMLController());
    }
    
    private void launchSlipperySlide(Event e){
        logger.info("Launching  forces...");
        MainApp.switchScene(MainApp.SLIPPERY_SLIDE_LAYOUT, new SlipperySlideFXMLController());
    }
    
    private void launchPeriodicTable(Event e){
        logger.info("Launching  periodic table...");
        MainApp.switchScene(MainApp.PERIODIC_TABLE_LAYOUT, new PeriodicTableFXMLController());
    }

    private void handleOpenPeriodicTable(Event e) {
        logger.info("Launching  periodic table...");
        try {
            ElementsController controller = new ElementsController();
            List<ElementInfo> elements = controller.loadElementsData();
            for (ElementInfo element : elements) {
                System.out.println(element);
            }
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Driver.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Upvotes: 0

Views: 49

Answers (0)

Related Questions