Question

I have a JDialog with a button/textfield for the user to select a file. Here's the code:

FileDialog chooser = new FileDialog(this, "Save As", FileDialog.SAVE );
String startDir = saveAsField.getText().substring( 0, saveAsField.getText().lastIndexOf('\\') );
chooser.setDirectory(startDir);
chooser.setVisible(true);
String fileName = chooser.getFile();

My problem is that instead of seeing an All Files filter, I want to provide a custom filter, e.g. for Word docs or something. I setup a custom FilenameFilter using setFilenameFilter(), but it didn't seem to work. I did notice that it says in the docs that the custom filter doesn't work in Windows (this runs in Windows XP/Vista/7). Here was my implementation of the filter:

chooser.setFilenameFilter( new geFilter() );
public class geFilter implements FilenameFilter {
    public boolean accept(File dir, String name) {
        return name.endsWith( ".doc" ) || name.endsWith( ".docx" );
    }
}

Am I doing something wrong here? Also, I want a description to appear in the box, like "Microsoft Word (*.doc *.docx)" but I'm not sure how to do that.

Any and all help is appreciated.

Was it helpful?

Solution

AWT isn't really the preferred way of writing Java GUI apps these days. Sun seems to have mostly abandoned it. The two most popular options are Swing and SWT. So I think they didn't really develop the APIs very extensively to add modern features. (err, to answer your question: No you don't appear to be able to do that with AWT)

Swing has the advantage that it is truly write-once-run-anywhere and it can look exactly the same everywhere. There are Look & Feels that try to make Swing look native, some are better than others (Mac isn't terrible, Windows is okay, GTK isn't). Still, if you want an app that really looks and acts EXACTLY the same everywhere, Swing will let you do that. Plus it runs out-of-the-box without any extra libraries. Performance isn't great.

Swing's JFileChooser will let you do what you want. Create a subclass of FileFilter and call setFileFilter on the JFileChooser.

SWT takes the write-once-run-anywhere to the opposite extreme. You still have one codebase that you write against, but it actually uses the native widgets on each platform so it generally looks like a native app (not perfect everywhere, but still impressive). It's fast and pretty reliable in my experience. Eclipse (and other high profile software) uses SWT so it's in pretty heavy use. But it does require platform-specific JARs and DLLs.

OTHER TIPS

since you are using JDialog, that is a swing class why not using JFileChooser?

 JFileChooser fc = new JFileChooser("C:\\");
 fc.setFileFilter(new FileNameExtensionFilter("Microsoft Word (*.doc, *.docx)", "doc", "docx"));

FileNameExtensionFilter is a nice Java 6 class that does exactly what you want.

I am also trying to do that. I want to use FileDialog instead of JFileChooser.

I found the answer here: http://www.rgagnon.com/javadetails/java-0247.html

He says that "on the Win platform, the setFilenameFilter method don't work. We must use the setFile method instead to set a filter."

There is source code at the specified link.

I tested and it works:

FileDialog fd = new FileDialog((Frame) null, "Save File", FileDialog.SAVE);
fd.setFile("*.txt");
fd.setVisible(true);

String file = fd.getFile();
System.out.println(file);
System.exit(0);

You can call the native Windows Filedialog (CFileDialog) with JNI. Filters can be set for CFileDialog easily.

I wrote a simple wrapper class for CFileDialog several months ago, If you are interested, you can get the source and binary from

Xfiledialog project on google code

If you ever use JavaFX 2, the FileChooser class will do exactly what you need without any of JFileChooser/FileDialog problems. You can also embed JavaFX 2 components inside Swing applications, but you need JavaFX runtime.

Example:

    FileChooser fc = new FileChooser();
    FileChooser.ExtensionFilter filter;
    filter = new FileChooser.ExtensionFilter("Text files (*.txt)", "*.txt");
    fc.getExtensionFilters().add(filter);
    File f = fc.showOpenDialog(primaryStage);
    System.out.println(f);

Just use setFilenameFilter method of the FileDialog instance fd:

            fd.setFilenameFilter(new FilenameFilter()
                            {
                                @Override
                                public boolean accept(File file, String s)
                                {
                                    // enter code to return TRUE or FALSE here
                                    return s.contains(".txt");
                                }
                            });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top