In MATLAB, there's a function that prompts the user to choose one or more files - uigetfile
, and there's another function which allows the user to choose a folder - uigetdir
.
I would like to provide the user an ability to choose either a file or a folder, using a single window, as this is important for the UX I'm trying to create.
So far, the only solution I found that uses the above functions1 requires an additional step of asking the user what type of entity they would like to select, in advance, and calling the appropriate function accordingly - which I find inconvenient.
So how can I have a dialog which allows me to select either one?
We can use a Java component for this, specifically JFileChooser
, and make sure that we provide it with the FILES_AND_DIRECTORIES
selection flag.
%% Select entity:
jFC = javax.swing.JFileChooser(pwd);
jFC.setFileSelectionMode(jFC.FILES_AND_DIRECTORIES);
returnVal = jFC.showOpenDialog([]);
switch returnVal
case jFC.APPROVE_OPTION
fName = string(jFC.getSelectedFile());
case jFC.CANCEL_OPTION
% do something with cancel
case jFC.ERROR_OPTION
% do something with error
otherwise
throw(MException("fileFolderChooser:unsupportedResult", ...
"Unsupported result returned from JFileChooser: " + returnVal + ...
". Please consult the documentation of the current Java version (" + ...
string(java.lang.System.getProperty("java.version")) + ")."));
end
%% Process selection:
switch true % < this is just some trick to avoid if/elseif
case isfolder(fName)
% Do something with folder
case isfile(fName)
% Do something with file
otherwise
throw(MException('fileFolderChooser:invalidSelection',...
'Invalid selection, cannot proceed!'));
end
This produces a familiar-looking dialog as follows, which works exactly as expected:
JFileChooser
has a variety of interesting settings like multi-selection and showing hidden files/folders, as well as standard settings like changing the dialog title, the button texts and tooltips, etc. It can also be used as either an "Open" dialog or a "Save" dialog simply by setting a value.
Tested on R2018a, with Java 1.8.0_144 (output of java.lang.System.getProperty("java.version")
).