How do I open the JavaFX FileChooser from a controller class?

48,951

Solution 1

For any node in your scene (for example, the root node; but any node you have injected with @FXML will do), do

chooser.showOpenDialog(node.getScene().getWindow());

Solution 2

You don't have to stick with the Stage created in the Application you can either:

@FXML protected void locateFile(ActionEvent event) {
    FileChooser chooser = new FileChooser();
    chooser.setTitle("Open File");
    File file = chooser.showOpenDialog(new Stage());
}

Or if you want to keep using the same stage then you have to pass the stage to the controller before:

    FXMLLoader loader = new FXMLLoader(getClass().getResource("yourFXMLDocument.fxml"));
    Parent root = (Parent)loader.load();
    MyController myController = loader.getController();
    myController.setStage(stage);

and you will have the main stage of the Application there to be used as you please.

Solution 3

Alternatively, what worked for me: simply put null.

@FXML
private void onClick(ActionEvent event) {
    File file = fileChooser.showOpenDialog(null);
    if (file != null) {
       //TODO
    }
}

Solution 4

From a menu item

public class SerialDecoderController implements Initializable {

  @FXML
  private MenuItem fileOpen;

  @Override
  public void initialize(URL url, ResourceBundle rb) {
    // TODO
 }    


public void fileOpen (ActionEvent event) {

    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("Open Resource File"); 
    fileChooser.showOpenDialog(fileOpen.getParentPopup().getScene().getWindow());

}
Share:
48,951
Electric Coffee
Author by

Electric Coffee

Software Engineer at Valhal Connect My Fields of interest are programming in Java, Scala, F#, Haskell, and Objective-C, FLOSS, POSIX, digital design, and making stuff.

Updated on July 11, 2022

Comments

  • Electric Coffee
    Electric Coffee almost 2 years

    My problem is that all the examples of using FileChooser requires you to pass in a stage. Only problem is that my UI is defined in an fxml file, which uses a controller class separate from the main stage.

    @FXML protected void locateFile(ActionEvent event) {
        FileChooser chooser = new FileChooser();
        chooser.setTitle("Open File");
        chooser.showOpenDialog(???);
    }
    

    What do I put at the ??? to make it work? Like I said, I don't have any references to any stages in the controller class, so what do I do?

  • Electric Coffee
    Electric Coffee over 9 years
    and where do I get the root node from? do I have to define an fx:id or am I completely missing the idea?
  • James_D
    James_D over 9 years
    Yes, define an fx:id. But you don't have to use the root node, just use anything for which you already have an fx:id and have injected into the controller (all your nodes are in the same scene...). You could also do Node node = (Node) event.getSource(); but I like that less, because of the downcast.
  • jewelsea
    jewelsea over 9 years
    I think it is better to set the owner of the dialog to the correct stage and not some made up stage. See showOpenDialog javadoc "If the owner window for the file dialog is set, input to all windows in the dialog's owner chain is blocked while the file dialog is being shown.". If you don't specify the correct stage, the modal dialog blocking functionality of the FileChooser is not enabled. It is usually desirable to have modal blocking in a FileChooser.
  • Mansueli
    Mansueli over 9 years
    @jewelsea It is a better practice o keep using the same Stage, and that's why I show in my answer one way to do it. But it should be noted that best practice isn't the only practice.
  • Sargon1
    Sargon1 over 8 years
    Could you please elaborate on this answer a bit? For starters, what's a "node" in this context, and how do I "define a fx:id", and where? I copied over the line from above, but the "node" part still cannot be resolved.
  • David Artmann
    David Artmann over 7 years
    To comment on @Sargon1 request: A node is any widget in the UI which inherits from Node. A "fx:id" is the name of the Java UI Object in your class. You connect the associated fxml component over the Scenebuilder App (also possible directly in the fxml code, of course): when you open an fxml file and chose the desired widget, you simply set the id (name of object) under the right accordion-menu "Code" and the appearing field "fx:id".
  • GoldBishop
    GoldBishop over 2 years
    curious....won't null create a non-modal dialog box? which in most cases, a File Open dialog is typically Modal
  • Alexander
    Alexander about 2 years
    fileOPen.getParentPopup seems to me strange. fileOpen is name of method in given context