简体   繁体   中英

JavaFX Passing Stage/Switching Scene

I have decided to update my application using JavaFXML, However I am having difficulties passing a scene into my controller. Here is my Controller;

public class MainApp extends Application {

@FXML
public Stage primaryStage;

@FXML
private AnchorPane rootLayout;
@FXML
private JobInterface jInterface;

@Override
public void start(Stage primaryStage) {
    primaryStage = new Stage();
    setPrimaryStage(primaryStage);
    initRootLayout();
}

@FXML
public void initRootLayout(){
    try {
        primaryStage = getPrimaryStage();
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(MainApp.class.getResource("MainInterface.fxml"));
        rootLayout = (AnchorPane) loader.load();        
        Scene scene = new Scene(rootLayout);    
        primaryStage.setScene(scene);
        primaryStage.show();
        setPrimaryStage(primaryStage);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@FXML
private void setJobLayout(){
    primaryStage = getPrimaryStage();
    jInterface = new JobInterface();
    jInterface.initJobLayout();
    primaryStage.setScene(jInterface.getScene());
}

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

public Stage getPrimaryStage() {
    return primaryStage;
}

public void setPrimaryStage(Stage primaryStage) {
    this.primaryStage = primaryStage;
}
}

Here is a method that is changing the scene using a different FXML file and attempting to pass the scene back to the controller;

public class JobInterface {

private AnchorPane rootLayout;
private Scene scene;

public void initJobLayout(){
    try {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(MainApp.class.getResource("JobInterface.fxml"));
        rootLayout = (AnchorPane) loader.load();
        scene = new Scene(rootLayout);
        setScene(scene);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public Scene getScene() {
    return scene;
}

public void setScene(Scene scene) {
    this.scene = scene;
}
}

The issue I'm having now is a NullPointerException on this line in the main app;

primaryStage.setScene(jInterface.getScene());

I am trying to pass a Stage between methods so that I can only update the Scene and not have to open a new Stage everytime a new method is called. Any ideas on where I am going wrong?

There should be no need to pass the stage or scene. Your Main will load the fxml resource which will have your fxml controller 'in charge' of your fxml file.

    @Override
    public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("jobController.fxml"));        
    Scene scene = new Scene(root);        
    stage.setScene(scene);
    stage.show();
}

Your controller might look something like this (depending on your fxml design):

public class JobController {

    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event) {        
        label.setText("This is the controller speaking");
    } 
}

Now you can 'control' your stage (scene) from the controller. If you are going to create another class which also has to update the scene, pass a reference to the controller to it eg from the controller:

TimeClock timeClock = new TimeClock();
timeClock.init(this);

and then in TimeClock.java you have:

private final JobController controller;

public void init (JobController control){ 
    this.controller = control;
}

Now you can access any public method in your controller from the TimeClock class. Eg

controller.updateLabel("Time clock speaking!");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM