1

Sorry I am new to JavaFX. My setup: I have one main FXML GUI which is displayed the entire time. Inside this main GUI I have loaded another FXML in an AnchorPane.

The second FXML is loaded into this AnchorPane (which is in the main GUI) initially using:

@FXML
private AnchorPane rootSetPane;

I then use the rootSetPane from there. This is the AnchorPane which is inside the same main GUI fxml.

<AnchorPane fx:id="rootSetPane" layoutX="228.0" prefHeight="710.0" prefWidth="887.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="228.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />

Initialize main controller (main GUI is displayed the entire time)

@Override
public void initialize(URL url, ResourceBundle rb) {
    AnchorPane paneHome;
    try {
        paneHome = FXMLLoader.load(getClass().getResource("HomePage.fxml"));
        rootSetPane.getChildren().setAll(paneHome);          
    } catch (IOException ex) {
        Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

An example of a working method in this main class (this is called from a button in the same main FXML):

@FXML
private void foodFinder(ActionEvent event) throws IOException {      
    AnchorPane paneFoodFinder = FXMLLoader.load(getClass().getResource("ScreenFoodFinder.fxml"));

    rootSetPane.getChildren().setAll(paneFoodFinder);    
}

An example of a method that is not working (this is called using an object):

public void setPanel() throws IOException {
   AnchorPane newPane = FXMLLoader.load(getClass().getResource("NewPane.fxml"));
rootSetPane.getChildren().setAll(newPane);  
}

I set this second pane several times during the program using buttons in the main GUI (this works). The problem occurs when attempting to set this pane from outside the main controller class. I can not use an instance of the Main class and call a method to access rootSetPane (and I can't make the rootSetPane static). I am getting a NullPointerException. I am sure this is a amateur mistake. Is there a way I can change this rootSetPane using a method like the ones above.

Or do I have to make other classes to manage my screens. The easiest (even dirty) solution would be appreciated.
It would also work if I were able to fire a button in the main GUI, but this is resulting in the same issue (NullPointerException). I have a feeling that I can not reference the elements using an object of the class and I also can not make these elements static.

lolftw
  • 35
  • 7

2 Answers2

0

Check if getClass().getResource("NewPane.fxml") is pointing to right file.

  • The file name is correct. but an error (same error as above) occurs with the 'rootSetPane'. This line does not work: 'rootSetPane.getChildren()'. – lolftw Sep 17 '16 at 16:05
  • How do you initialize `rootSetPane`? – Michał Piątkowski Sep 17 '16 at 16:06
  • The answer to that question I think is no. I have called to method from another class using an object of the main gui controller. How can I call this method another way (or do it properly?). – lolftw Sep 17 '16 at 16:33
0

You can make a class that extends AnchorPane.That class will be the controller of the fxml.So you can create an instance of it like:

 SpecialAnchorClass anchor = new SpecialAnchorClass();

Mention that in the SceneBuilder you have to check: enter image description here

So your SpecialAnchorClass will be like this:

public class SpecialAnchorClass extends AnchorPane implements Initializable{

    //..@fxml nodes

    /**
     * Constructor
     */
   public SpecialAnchorClass(){
         //FXMLLOADER
        FXMLLoader loader = new FXMLLoader(getClass().getResource("..path to fxml file"));
        loader.setController(this);
        loader.setRoot(this);

        try {
            loader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

   @Override
     public void initialize(URL location, ResourceBundle resources) {


           //when this method is called every fxml component has been initialized
     }

}
GOXR3PLUS
  • 6,877
  • 9
  • 44
  • 93
  • When would I create the object of this class in the sequence of my program? – lolftw Sep 17 '16 at 17:01
  • @lolftw You can create it as a member of the Main class,or you can create it whenever you want and make it static final. – GOXR3PLUS Sep 17 '16 at 17:03
  • As I mentioned I am completely new to this and I think that I am implementing this wrong. I am getting this error:`javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.` – lolftw Sep 17 '16 at 17:24
  • @lolftw Yes that's why added the image.You have to check the [Use fx:root construct].How have you made the fxml? – GOXR3PLUS Sep 17 '16 at 17:26
  • @lolftw Have a look here http://stackoverflow.com/questions/23600926/how-to-understand-and-use-fxroot-in-javafx#23601288 – GOXR3PLUS Sep 17 '16 at 17:30
  • I am looking into it. The FXML that I created in SceneBuilder is made up of one big AnchorPane, and then a smaller AnchorPane inside it. I want to be able to load other FXMLs into this smaller AnchorPane. – lolftw Sep 17 '16 at 17:40
  • @lolftw In the fxml file create only the empty BigAnchorPane.Then create an instance of SpecialAnchorClass.Use the SpecialAnchorClass to add the fxmls you want each time. – GOXR3PLUS Sep 17 '16 at 17:52
  • Thanks for the help. I have decided to use another method because of my lack of knowledge. But this method was the most helpful. – lolftw Sep 17 '16 at 18:43
  • @lolftw Always try to use the most simple but well defined design.In the situation here you can have an AnchorPane and multiple fxmls and every time change the fxml.This video is about core design principles https://www.youtube.com/watch?v=llGgO74uXMI&list=PLRsbF2sD7JVpQsKP-AQcTWEk-gj1RtyYI&index=3 – GOXR3PLUS Sep 17 '16 at 18:51
  • Thanks. I didn't use the method because I have already gotten far using lots of fxml files and separate controller classes and unfortunately I have a deadline soon... not much time to learn new things. – lolftw Sep 17 '16 at 18:58