I'm writing a diagram editor in java. This app has the option to export to various standard image formats such as .jpg, .png etc. When the user clicks File->Export, you get a JFileChooser which has a number of FileFilters in it, for .jpg, .png etc.

Now here is my question:

Is there a way to have the extension of the default adjust to the selected file filter? E.g. if the document is named "lolcat" then the default option should be "lolcat.png" when the png filter is selected, and when the user selects the jpg file filter, the default should change to "lolcat.jpg" automatically.

Is this possible? How can I do it?

edit:
Based on the answer below, I wrote some code. But it doesn't quite work yet. I've added a propertyChangeListener to the FILE_FILTER_CHANGED_PROPERTY, but it seems that within this method getSelectedFile() returns null. Here is the code.

7 Answers
7

It looks like you can listen to the JFileChooser for a change on the FILE_FILTER_CHANGED_PROPERTY property, then change the extension of the selected file appropriately using setSelectedFile().

EDIT: You're right, this solution doesn't work. It turns out that when the file filter is changed, the selected file is removed if its file type doesn't match the new filter. That's why you're getting the null when you try to getSelectedFile().

Have you considered adding the extension later? When I am writing a JFileChooser, I usually add the extension after the user has chosen a file to use and clicked "Save":

You can also use a PropertyChangeListener on the SELECTED_FILE_CHANGED_PROPERTY prior to attaching your suffix. When the selected file gets checked against the new filter (and subsequently set to null), the SELECTED_FILE_CHANGED_PROPERTY event is actually fired before the FILE_FILTER_CHANGED_PROPERTY event.

If the evt.getOldValue() != null and the evt.getNewValue() == null, you know that the JFileChooser has blasted your file. You can then grab the old file's name (using ((File)evt.getOldValue()).getName() as described above), pull off the extension using standard string parsing functions, and stash it into a named member variable within your class.

That way, when the FILE_FILTER_CHANGED event is triggered (immediately afterwards, as near as I can determine), you can pull that stashed root name from the named member variable, apply the extension for the new file filter type, and set the JFileChooser's selected file accordingly.

The getFileName() method of javax.swing.plaf.basic.BasicFileChooserUI (the descendant of FileChooserUI returned by JFileChooser.getUI()) will return the contents of the dialog's text box that is used to type in the file name. It seems that this value is always set to a non-null String (it returns an empty string if the box is empty). On the other hand, getSelectedFile() returns null if the user has not selected an existing file yet.

It seems that the dialog's design is governed by the 'file selection' concept; that is, while the dialog is visible getSelectedFile() only returns a meaningful value if the user has already selected an existing file or the program called setSelectedFile(). getSelectedFile() will return what the user typed in after the user clicks the approve (i.e. OK) button.

The technique will only work for single-selection dialogs, however changing file extension based on selected filter should also make sense for single files only ("Save As..." dialogs or similar).

This design was a subject of a debate at sun.com back in 2003, see the link for details.

The use of getAbsolutePath() in the previous change the current directory.
I was surprised when the JFileChooser dialog displaying "My documents" directory change to the Netbeans's project directory when I selected a different FileFilter, so I changed it to use getName().
I also used the JDK 6 FileNameExtensionFilter.