17

enter image description here

If we have a Stage then Scene includes 2 Panes the 1st Pane contains Button and the 2nd Pane is empty could we load other fxml file inside this 2nd Pane?

fxml1: VBox
               |_Pane1-->Button
               |_Pane2
///////////////
fxml2: Pane--> Welcome to fxml 2
"when we click the button load the fxml2 inside Pane2 of fxml1"

Then after click

enter image description here


====I finally found this works after trying !====Thank you guys

@FXML Pane secPane;
public void loadFxml (ActionEvent event) {
Pane newLoadedPane =        FXMLLoader.load(getClass().getResource("/application/fxml2.fxml"));
secPane.getChildren().add(newLoadedPane); 
}  
Hussein Ahmed
  • 730
  • 2
  • 7
  • 17
  • You can indeed load an fxml file dynamically. If your question is any more involved than that, you'll have to edit it to add a bit more about your actual code and what you've tried that hasn't worked. – Steve K Nov 17 '15 at 02:34
  • I try by this but doesn't work @FXML Pane secPane; public void loadFxml (ActionEvent event) { secPane = FXMLLoader.load(getClass().getResource("/application/fxml2.fxml")); } – Hussein Ahmed Nov 17 '15 at 02:38
  • and what specific error are you getting when you try to run that? – Steve K Nov 17 '15 at 02:42
  • java.lang.NullPointerException – Hussein Ahmed Nov 17 '15 at 02:52
  • And what's null on the specific line that went wrong? the FXMLLoader? the resolved resource? – Steve K Nov 17 '15 at 02:54
  • No need to edit question to add an answer, just [select the correct answer from the available answers](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). You can [accept your own answer to your question](http://stackoverflow.com/help/self-answer) if you wish. – jewelsea Nov 20 '15 at 00:55
  • Thank you jewelsea, but i have less than 15 REPUTATION to select my answer as an answer, do u mind if select my answer? – Hussein Ahmed Nov 20 '15 at 02:29
  • I'd love to Hussein but StackOverflow only permits the asker to accept an answer. I updated your question, to give you 5 more reputation points, so almost there... :-) – jewelsea Nov 24 '15 at 19:28

3 Answers3

27

I finally found this works after trying !

@FXML Pane secPane;
public void loadFxml (ActionEvent event)  {
  Pane newLoadedPane =  FXMLLoader.load(getClass().getResource("/application/fxml2.fxml"));
  secPane.getChildren().add(newLoadedPane);
}
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
Hussein Ahmed
  • 730
  • 2
  • 7
  • 17
5

Just replacing the field in your controller class won't change the scene graph.

secPane is just a reference to a node in the scene graph.

If secPane is just a placeholder, you could replace it in the parent's child list:

public void loadFxml (ActionEvent event) {
    // load new pane
    Pane newPane = FXMLLoader.load(getClass().getResource("/application/Login2.fxml"));

    // get children of parent of secPane (the VBox)
    List<Node> parentChildren = ((Pane)secPane.getParent()).getChildren();

    // replace the child that contained the old secPane
    parentChildren.set(parentChildren.indexOf(secPane), newPane);

    // store the new pane in the secPane field to allow replacing it the same way later
    secPane = newPane;
}

This assumes of course, that getClass().getResource("/application/Login2.fxml") yields the correct resource and does not return null (which happens if no resource with the given name is available)

fabian
  • 80,457
  • 12
  • 86
  • 114
1

You can implement something like this :

 public void start(Stage primaryStage) throws IOException {
            primaryStage.setTitle("Title");
            primaryStage.setScene(createScene(loadMainPane("path_of_your_fxml")));
            primaryStage.show();

    }

    private Pane loadMainPane(String path) throws IOException {
        FXMLLoader loader = new FXMLLoader();

        Pane mainPane = (Pane) loader.load(
                getClass().getResourceAsStream(path));

        return mainPane;
    }


    private Scene createScene(Pane mainPane) {
        Scene scene = new Scene(mainPane);
      return scene;
    }

Then you can create a separate class call Navigation to store all your fxml paths:

public class Navigator {

private final String P1;
private final String P2;
//then you can implement getters...
public String getP1() {
    return P1;
}

public String getP2() {
    return p2;
}

private static FxmlController Controller;

    public static void loadPane(String fxml) {
    try {
        FxmlController.setPane(
                (Node) FXMLLoader.load(Navigator.class.getResource(fxml)));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public Navigator() throws IOException {
    this.P1 = "p1.fxml";
    this.P2 = "p2.fxml";}

Then you can load your pane in your button like below:

@FXML
    private void btnAction(ActionEvent event) throws IOException {
    Navigator.load(new Navigator().getP1());
    ..

.

Madushan Perera
  • 2,568
  • 2
  • 17
  • 36