J/Link Tutorial

Creating a file chooser dialog box

A useful feature for Mathematica programs is the ability to produce a file chooser dialog box, such as the typical Open or Save dialog boxes. You could use such a dialog box to prompt a user for an input file or a file into which to write data. This is easily accomplished across platforms with Java, specifically with the JFileChooser class in the standard Swing library.

Starting Out

If you have Mathematica 4, you may be aware of the new experimental function called FileBrowse[], which displays a file browser in the front end. Although this function is usable, it has several shortcomings compared to the Java technique presented here. The first of these has already been mentioned: it is only available in Version 4, where it is marked as “experimental” and thus likely to change in the future. Second, it requires the front end to be in use. Third, it is not customizable, so you always get a “Save file as:” dialog box and concomitant behavior, which is not appropriate for an Open-type dialog box. The JFileChooser class used here allows very sophisticated customization including setting the initial directory, masking out files based on their names or properties, controlling the title and text on the various buttons, supplying functions to validate the choice before the dialog box is allowed to be dismissed, allowing for multiple file selection, and allowing directories to be selected instead of files.

The FileChooserDialog function takes three string arguments. The first is the title of the dialog box (for example, "Select a data file to import"), the second is the text to appear on what is essentially the OK button (typically this will be Open or Save), and the third is the starting directory. You can also supply no arguments and get a default Open dialog box that starts in the kernel’s current directory.

FileChooserDialog[]  :=  
      FileChooserDialog["Select a file:",  "Open",  
        Directory[]]

\(FileChooserDialog[title_String, \ okText_String, \ dir_String]\  := 
	
      JavaBlock[
		Module[{dlg, \ chosenFile, \ 
            result\  = \ Null}, 
			InstallJava[]; 
			dlg\  = \ 
            JavaNew["javax.swing.JFileChooser"]; 
			dlg@
            setCurrentDirectory[
              JavaNew["java.io.File", \ dir]]; 
			dlg@
            setDialogTitle[title]; 
			 (*\ 
            The\ showDialog\ function\ will\ not\ return\ until\ the\ dialog\ box\ is\ \(\(dismissed\)\(.\)\)\ *) 
			If[
            dlg@showDialog[Null, \ okText]\  === \ 
              JFileChooser`APPROVEUOPTION, 
				chosenFile\  = \ 
              dlg@getSelectedFile[]; 
				If[
              chosenFile\  =!= \ Null, 
					result\  = \ 
                chosenFile@
                  getPath[]
				]
			]; 
			result
		]
	]\)

There are two interesting points to mention about this code. First, there is no need to use DoModal because showDialog will not return until you dismiss the dialog box. DoModal is a way to force Mathematica to stall until the dialog box or other window is dismissed. Here, you get this behavior from showDialog. DoModal puts the kernel into a loop where it is ready to receive input from Java, so you can script some of the functionality of the dialog box in Mathematica using MathListener objects or trigger other computations like printing text or plots in a notebook window. This file chooser dialog box does not need to use Mathematica until it returns the selected file.

Second, the name of the constant that showDialog returns to indicate that you clicked the Save or Open button instead of the Cancel button must be chosen carefully. The name of this constant in Java is JFileChooser.APPROVE_OPTION. Java names map to Mathematica symbols, so they must be translated if they contain characters that are not legal in Mathematica symbols. For example, underscores are converted to a U when they appear in symbols, so the Mathematica name of this constant is JFileChooser`APPROVEUOPTION. See Section 1.1.6 of the J/Link User Manual for more information.

Final Code

The following example combines all the above elements for J/Link to produce a file chooser dialog box.

Needs["JLink`"]

FileChooserDialog[] := FileChooserDialog["Select a file:", "Open", Directory[]]

FileChooserDialog[title_String, okText_String, dir_String] :=
	JavaBlock[
		Module[{dlg, chosenFile, result = Null},
			InstallJava[];
			dlg = JavaNew["javax.swing.JFileChooser"];
			dlg@setCurrentDirectory[JavaNew["java.io.File", dir]];
			dlg@setDialogTitle[title];
			If[dlg@showDialog[Null, okText] === JFileChooser`APPROVEUOPTION,
				chosenFile = dlg@getSelectedFile[];
				If[chosenFile =!= Null,
					result = chosenFile@getPath[]
				]
			];
			result
		]
	]

Examples

You must call InstallJava prior to running these examples.

InstallJava[];

This is a simple Open-style dialog box.

FileChooserDialog[]

This is a simple Save-style dialog box.

FileChooserDialog["Save data as:", "Save", Directory[]]