With a running JavaFX application, open a new window with its own, separate controller class

16,448

Solution 1

Don't load the FXML twice like that. You can load multiple times the same .fxml document (multiple scene graph / controllers) but if you want to do together loading the scene graph and initializing the controller you have to call the fxml loader only once.

Here is an example

    FXMLLoader loader = new FXMLLoader(getClass().getResource("ServerConfigChooser.fxml"));
    ServerConfigChooser controller = new ServerConfigChooser();
    loader.setController(controller);
    loader.setRoot(controller);
    Parent root;
    try {
        root = (Parent) loader.load();
        Scene scene = new Scene(root, 320, 200);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
    } catch (IOException ex) {
        Logger.getLogger(ServerConfigChooser.class.getName()).log(Level.SEVERE, null, ex);
    }

Note that

  • your controller should extend the node type of the root node of your .fxml document
  • your .fxml document should use fxroot construct, see this doc (you can set this in scene builder)
  • you should remove the controller from the fxml root element. It will conflict with this way of using the FXMLLoader class

For example the controller class

public class ServerConfigChooser extends AnchorPane implements Initializable {
   ...
}

And the .fxml

<fx:root type="javafx.scene.layout.AnchorPane" id="AnchorPane" prefHeight="200.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">

Solution 2

The problem here is probably how you are loading the ServerConfigChooser (I get the feeling the FXML is loaded twice or something like that). The following should work:

try {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("ServerConfigChooser.fxml"));
    ServerConfigChooser controller = new ServerConfigChooser();
    loader.setController(controller);
    Parent root = (Parent) loader.load();

    Stage stage = new Stage();
    stage.setScene(new Scene(root));
    stage.show();
}
catch(...) {...}

Also check that you don't specify fx:controller in ServerConfigChooser.fxml (could conflict, haven't actually tried).

Share:
16,448

Related videos on Youtube

Kyte
Author by

Kyte

Updated on June 04, 2022

Comments

  • Kyte
    Kyte almost 2 years

    I'm using SceneBuilder in conjunction with Netbeans' JavaFX library for this project. I use Scenebuilder to create the fxml and netbeans for the controller classes. The goal is to build a fairly complex app that is to be deployed.

    I can launch a JavaFX application and hook up the controller class just fine. However, when I try to open a new window I can't seem to bind a controller class to the new window. To keep things simple I would like to have a separate controller class for the new window due to a complex back-end.

    TL;DR -- Trying to open a new window on JavaFX application with a controller class. Controller class isn't binding.

    Code samples below

    Model class -- wrapper for launching the application

    public class Model extends Application{
        public static void main(String[] args){
             Application.launch(Model.class, args);
        }
        @Override
        public void start(Stage stage) throws Exception{
            Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
            stage.setScene(new Scene(root));
            stage.show();
        }
    }
    

    Sample.fxml -- fxml file for the main application

    Sample.java -- extends Initializable, is the controller class for Sample.fxml. Below is code snippet where I try to open the new window titled "ServerConfigChooser

    try{
        Parent root = FXMLLoader.load(getClass().getResource("ServerConfigChooser.fxml"));
        FXMLLoader loader = new FXMLLoader(getClass().getResource("ServerConfigChooser.fxml"));
        ServerConfigChooser controller = new ServerConfigChooser();
    
        loader.setController(controller);
        loader.setRoot(root);
    
        Stage stage = new Stage();
        stage.setScene(new Scene(root));
        stage.show();
    } catch (IOException ex)
    

    ServerConfigChooser.java -- implements Initializable

    This is where I have the problems. I cannot simply declare variables with the same fxid as the variables in the .fxml file. The initialize() method does not fire when the class is called.

    The reason for the constructor in the ServerConfigChooser class is that I could not fire the initialize() method automatically. I fire that manually within the constructor.

    Any solutions are welcome!

    • jth41
      jth41 over 10 years
      A word to the wise. Posting questions on Sundays is generally the least active time of the week for SO. Wait for Monday for better results