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 FileFilter
s 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.
package nl.helixsoft;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;
public class JFileChooserTest {
public class SimpleFileFilter extends FileFilter {
private String desc;
private List<String> extensions;
private boolean showDirectories;
/**
* @param name example: "Data files"
* @param glob example: "*.txt|*.csv"
*/
public SimpleFileFilter (String name, String globs) {
extensions = new ArrayList<String>();
for (String glob : globs.split("\\|")) {
if (!glob.startsWith("*."))
throw new IllegalArgumentException("expected list of globs like \"*.txt|*.csv\"");
// cut off "*"
// store only lower case (make comparison case insensitive)
extensions.add (glob.substring(1).toLowerCase());
}
desc = name + " (" + globs + ")";
}
public SimpleFileFilter(String name, String globs, boolean showDirectories) {
this(name, globs);
this.showDirectories = showDirectories;
}
@Override
public boolean accept(File file) {
if(showDirectories && file.isDirectory()) {
return true;
}
String fileName = file.toString().toLowerCase();
for (String extension : extensions) {
if (fileName.endsWith (extension)) {
return true;
}
}
return false;
}
@Override
public String getDescription() {
return desc;
}
/**
* @return includes '.'
*/
public String getFirstExtension() {
return extensions.get(0);
}
}
void export() {
String documentTitle = "lolcat";
final JFileChooser jfc = new JFileChooser();
jfc.setDialogTitle("Export");
jfc.setDialogType(JFileChooser.SAVE_DIALOG);
jfc.setSelectedFile(new File (documentTitle));
jfc.addChoosableFileFilter(new SimpleFileFilter("JPEG", "*.jpg"));
jfc.addChoosableFileFilter(new SimpleFileFilter("PNG", "*.png"));
jfc.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent arg0) {
System.out.println ("Property changed");
String extold = null;
String extnew = null;
if (arg0.getOldValue() == null || !(arg0.getOldValue() instanceof SimpleFileFilter)) return;
if (arg0.getNewValue() == null || !(arg0.getNewValue() instanceof SimpleFileFilter)) return;
SimpleFileFilter oldValue = ((SimpleFileFilter)arg0.getOldValue());
SimpleFileFilter newValue = ((SimpleFileFilter)arg0.getNewValue());
extold = oldValue.getFirstExtension();
extnew = newValue.getFirstExtension();
String filename = "" + jfc.getSelectedFile();
System.out.println ("file: " + filename + " old: " + extold + ", new: " + extnew);
if (filename.endsWith(extold)) {
filename.replace(extold, extnew);
} else {
filename += extnew;
}
jfc.setSelectedFile(new File (filename));
}
});
jfc.showDialog(frame, "export");
}
JFrame frame;
void run() {
frame = new JFrame();
JButton btn = new JButton ("export");
frame.add (btn);
btn.addActionListener (new ActionListener() {
public void actionPerformed(ActionEvent ae) {
export();
}
});
frame.setSize (300, 300);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooserTest x = new JFileChooserTest();
x.run();
}
});
}
}
JFileChooser. setMultiSelectionEnabled(true) − To enable the multiple selection of file.
Click the Open a File button. Navigate around the file chooser, choose a file, and click the dialog's Open button. Use the Save a File button to bring up a save dialog. Try to use all of the controls on the file chooser.
JFileChooser has a method, getSelectedFile(). Which is a File. If you open the dialog with showSaveDialog() you should be able to get the File from that (file. getName()).
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":
if (result == JFileChooser.APPROVE_OPTION)
{
File file = fileChooser.getSelectedFile();
String path = file.getAbsolutePath();
String extension = getExtensionForFilter(fileChooser.getFileFilter());
if(!path.endsWith(extension))
{
file = new File(path + extension);
}
}
fileChooser.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
FileFilter filter = (FileFilter)evt.getNewValue();
String extension = getExtensionForFilter(filter); //write this method or some equivalent
File selectedFile = fileChooser.getSelectedFile();
String path = selectedFile.getAbsolutePath();
path.substring(0, path.lastIndexOf("."));
fileChooser.setSelectedFile(new File(path + extension));
}
});
How about this:
class MyFileChooser extends JFileChooser {
public void setFileFilter(FileFilter filter) {
super.setFileFilter(filter);
FileChooserUI ui = getUI();
if( ui instanceof BasicFileChooserUI ) {
BasicFileChooserUI bui = (BasicFileChooserUI) ui;
String file = bui.getFileName();
if( file != null ) {
String newFileName = ... change extension
bui.setFileName( newFileName );
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With