Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading new fxml in the same scene

Tags:

javafx

fxml

scene

I have 2 fxml files:

  • Layout (header, menubars and content)
  • Anchorpane (it's supposed to be placed inside the content from the other fxml file)

I would like to know how can I load the second file inside the content space from the "Master" scene. And is that a good thing to do working in javaFX or is it better to load a new scene?

I'm trying to do something like this, but it doesn't work:

@FXML private AnchorPane content;  @FXML private void handleButtonAction(ActionEvent event) {             content = (AnchorPane) FXMLLoader.load("vista2.fxml"); } 

Thanks for the help.

like image 385
Andre Avatar asked Sep 04 '13 16:09

Andre


People also ask

How do I add FXML to another FXML?

The <fx:include> tag can be used to include one fxml file into another. The controller of the included fxml can be injected into the controller of the including file just as any other object created by the FXMLLoader . This is done by adding the fx:id attribute to the <fx:include> element.

Can two FXML files have the same controller?

It's possible to use the same controller class for multiple FXML files, but your code will be really hard to follow, and it's a very bad idea. (Also note that using the fx:controller attribute, you will have a different controller instance each time you call FXMLLoader.


1 Answers

Why your code does not work

The loader creates a new AnchorPane, but you never add the new pane to a parent in the scene graph.

Quick Fix

Instead of:

content = (AnchorPane) FXMLLoader.load("vista2.fxml"); 

Write:

content.getChildren().setAll(FXMLLoader.load("vista2.fxml")); 

Replacing the content children with your new vista. The content itself remains in the scene graph, so when you set it's children, you are also attaching them to the scene graph at the same time.

You might need to play around with layout (e.g. work with auto resizing layouts like StackPanes rather than AnchorPanes) to get the exact behaviour you want.

Rather than just adopting the quick fix, I would advise reviewing the simple framework linked below as that might provide you with a more general purpose mechanism to get the behaviour you want.

Reference FXML Navigation Framework

I created a small framework for swapping fxml controlled content panes in and out of a portion of the main scene.

The mechanism of the framework is the same as suggested in kithril's answer.

  1. A main pane for the outer fxml acts as a holder for child panes.
  2. The main controller for the outer fxml supplies a public method that can be used to swap the child panes.
  3. A convenience navigator class is statically initialized with the main controller for the outer layout.
  4. The navigator provides a public static method to load a new child pane into the main container (by invoking a method on the main controller).
  5. Child panes are generated in the navigator by their respective fxml loaders.

Why a Framework

The framework seems like overkill for answering your question, and perhaps it is. However, I have found that the two most asked topic related to FXML are:

  1. Navigation between panes generated by FXML (this question).
  2. How to pass data between FXML controllers.

So I felt that a small demo framework was warranted for this case.

Sample Framework Output

The first screen shows the application layout displaying the first vista. The contents are a header which is defined in the main application layout and an aliceblue colored interchangable child content pane.

vista1

In the next screen, the user has navigated to the second vista, which retains the constant header from the main layout and replaces the original child pane with a new coral colored child content pane. The new child has been loaded from a new fxml file.

vista2

Looking for Something More Substantial?

A lightweight framework which is more extensive and better supported than the sample framework from this question is afterburner.fx.

Looking for Something Even Simpler?

Just swap out the scene root: Changing Scenes in JavaFX.

Other Options?

Animated Transitions and others: Switch between panes in JavaFX

like image 170
jewelsea Avatar answered Sep 18 '22 03:09

jewelsea