This question already has answers here:
Closed 3 years ago.
I use .fxml-Files for the view-layer of my application. Each fxml has a controller attached to it
<AnchorPane fx:controller="movielistjavafx.view.MainWindowController">
Let's assume I have a mainFrame and it's controller. The mainFrame.fxml is loaded in the start(Stage)
-method.
Now you would like to show a fileChooser which is attached to a Stage/Window/Whatever.
For that it would be good to let the fxml-controller know about the for example primaryStage
.
Is there any way to inject it to the controller, or does the FXML know at runtime to which scene and stage it belongs?
Only idea I have is to store primaryStage in some static context, but that seems not like a way to do it to me.
Not FXML but the nodes (controls) in FXML (or in its Controller) know to which scene and stage they belong at runtime (after being added to the scene).
In controller class,
...
@FXML private Label label;
...
// in some method block
Stage stageTheLabelBelongs = (Stage) label.getScene().getWindow();
Alternatively you can use CDI events to get the primary stage. Look the blog entry FXML & JavaFX powered by CDI & JBoss Weld.
Robust solution (can be used as a snippet): Take an event and then get control that fired that event. Use that control to get the Stage:
@FXML
private void browseDirectory(ActionEvent event) {
Stage stage = Stage.class.cast(Control.class.cast(event.getSource()).getScene().getWindow());
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(stage);
System.out.println(selectedDirectory.getAbsolutePath());
}
http://code.makery.ch/java/javafx-2-tutorial-part5
Here is a good tutorial for doing that with a sample code example
Controller...
//Application class type variable
public MainApp mainApp;
public Stage stage;
.........
.........
/**
* Is called by the main application to give a reference back to itself.
*
* @param mainApp
*/
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
}
.....
.........
@FXML
public void initialize(){
stage=mainApp.getStage();
}
Application class....
class MainApp extends Application{
Stage stage;
...
...
@Override
public void start(Stage stage) {
this.stage=stage;
FXMLLoader loader = new
FXMLLoader(MainApp.class.getResource("view/PersonOverview.fxml"));
PersonOverviewController controller = loader.getController();
controller.setMainApp(this);
}
...
,,
public getStage()
{
return this.stage;
}
}