Crashing when attempting to use FileChooserDialogBox according to example in docs

I need a file open browser for a GUI App (or plugin), and I want to try using the non-native juice version.

If you use the FileChooser class with the non-native flag, you have no real control over things like the size of the dialogBox when it opens.

So I see there is a FileChooserDialogBox class that directly makes a juce open/save browser. So I’m attempting to try the example code provided in FileChooserDialogBox.h.

There are a few errors in it, maybe it’s old. But here is my modified example.

This works but eventually crashes after trying to open it a few times in a row. Something with Listeners being deleted and crashing… I’m really not sure what I’m doing wrong.

// in mainComponent class:

    std::unique_ptr<juce::FileChooserDialogBox> dialogBox;
    std::unique_ptr<juce::FileBrowserComponent> browser;
    std::unique_ptr<juce::WildcardFileFilter> wildcardFilter;



// in code:
void MainComponent::loadFile()
{
        wildcardFilter.reset( new WildcardFileFilter ("*", String(), "Foo files"));

        browser.reset( new FileBrowserComponent (FileBrowserComponent::canSelectFiles | FileBrowserComponent::openMode,
                                                          File(),
                                                          wildcardFilter.get(),
                                                          nullptr));
        
        dialogBox.reset( new FileChooserDialogBox ("Open some kind of file",
                                                            "Please choose some kind of file that you want to open...",
                                                            *browser,
                                                            false,
                                                   findColour(ResizableWindow::backgroundColourId)));
        
        auto onFileSelected = [this] (int r)
        {
			// this seems some sort of error in the example, makes no sense
            // modalStateFinished (r);  //<== HERE
            
            auto theFile = browser->getSelectedFile (0);
            
            if (theFile.exists())
                DBG("GOOD!" + theFile.getFullPathName());
            else
            {
                DBG("CANCELLED!");
                return;
            }
        };
        
        dialogBox->centreWithDefaultSize (nullptr);
        dialogBox->enterModalState (true,
                                    ModalCallbackFunction::create (onFileSelected),
                                    true);

}

The first problem is that the dialog box is deleting itself when it is dismissed, but the unique_ptr will also attempt to delete the pointer when it goes out of scope or is reassigned. I think the final argument should be false instead.

The second problem is to do with lifetimes. The FileBrowserComponent and WildcardFileFilter must always outlive the FileChooserDialogBox. To ensure this,

  • add dialogBox = nullptr; to the top of loadFile, destroying the dialogBox before the wildcardFilter and browser are destroyed, and
  • declare the dialogBox data member after browser and wildcardFilter in the class definition (data members are destroyed from bottom to top).

@reuk - thanks much! That code example really could use some updating. :slight_smile:

@reuk - if I may bother you for one more second, this class doesn’t seem to work correctly. Using the above example, with your changes, it no longer crashes. But only the “Close” button exits the dialog. If you locate a file and choose “Open” button, you get the result in the callback, but the dialog does not dismiss…

…or perhaps I’m just not understanding how to use this…

I think you would need to manually hide or destroy the dialog inside the modal callback function.

Yeah, I eventually realized that…

A better piece of example code for this class would be nice in the future.

FileChooser is so much easier to use, but when you specify the non-native option, it creates one of these FileChooserDialogBox components and manages it - but there’s no way I can see to get at it or subclass it. Yes, there are some LookAndFeel methods for managing the contents of the dialog, but no way to, for example, change the default opening size of the window…