I'm finishing a part of my program that involves users being sent from a Login screen (FIRST fxml) to a second screen. This is supposed to happen whenever the program is loaded (based on remembrance).
When I run the program, it loads the FIRST and SECOND fxml, but continues to display the FIRST fxml (when it should display the SECOND). I can use an input (I.E button) with the same code to get from the first to the second screen.
I've tried using different loaders and using the .show() method every time I set a scene but none of these (or many variations thereof) have worked.
I printed when the methods were called - That's how I'm sure they're loaded (printline):
Here is a minimal representation of my code structure:
public class Main extends Application {
private static final FXMLLoader loader = new FXMLLoader();
private static Stage mainStage;
@Override
public void start(Stage primaryStage) throws Exception {
System.out.println("START METHOD");
mainStage = primaryStage; //Copy Reference
primaryStage.setScene(new Scene(Main.getLoader().load(Main.class.getResource("/res/screenOne.fxml"))));
primaryStage.show();
}
public static FXMLLoader getLoader() {
return loader;
}
public static Stage getStage() {
return mainStage;
}
}
/**
* FXML Controller class
*/
public class firstUI implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println("INIT1 METHOD");
try {
Parent root = Main.getLoader().load(getClass().getResource("/res/screenTwo.fxml"));
Main.getStage().setScene(new Scene(root));
} catch (Exception ex) {
Logger.getLogger(mainUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
/**
* FXML Controller class
*/
public class secondUI implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println("INIT2 METHOD");
System.out.println("Loaded Input UI");
}
}
Again, I want the code to load the firstUI, and then from the firstUI load the second.
The output instead (in debug if stage.show() comes first) seems to be:
You do not need a reference of the loader to change scene.
You can have a simple Main
like:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(new FXMLLoader().load(getClass().getResource("/res/screenOne.fxml"))));
primaryStage.show();
}
public static void main(String[] args) {
launch(null);
}
}
Where screenOne.fxml
can be (note the fx-id of the pane).
(To test you'll need to edit with the right controller path):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FirstUI">
<children>
<Label layoutX="155.0" layoutY="132.0" text="Screen 1">
<font>
<Font size="24.0" />
</font>
</Label>
<Button layoutX="264.0" layoutY="246.0" mnemonicParsing="false" onAction="#changeScene" prefHeight="26.0" prefWidth="102.0" text="Change Scene" />
</children>
</AnchorPane>
FirstUI
uses main
to update the scene:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;
public class FirstUI {
@FXML Pane main;
public void changeScene(ActionEvent e) {
try {
main.getScene().setRoot(new FXMLLoader().load(getClass().getResource("/res/screenTwo.fxml")));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
To make the code MRE here is screenTwo.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label layoutX="155.0" layoutY="132.0" text="Screen 2">
<font>
<Font size="24.0" />
</font>
</Label>
</children>
</AnchorPane>