<

Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x

Custom File Filtering Using Java File Choosers

Published on
32,036 Points
22,636 Views
4 Endorsements
Last Modified:
Awarded
Kevin Cross
Father, husband and general problem solver who loves coding SQL, C#, Salesforce Apex or whatever.
INTRODUCTION

Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.  

However, when your application has visual components, it might be a good idea to allow the user to select a file in a way similar to the Internet Browser's file choosers.

In a simple scenario, the usage of javax.swing.JFileChooser is all that is necessary to allow the user to browse the files and folders of the underlying Operating System.  But in most projects, the files that should be selected should have some specific properties - its location might be predefined, it might be restricted by size or by name, etc.  One option to solve these cases would be to allow the user to select any file or directory and then to check if this file/directory meets the requirements, notifying user for those that do not.  But a much better approach would be to show the user only the files that they can select from in the first place.

The following sections will take us through some code showing how the JFileChooser can be used in these more complicated scenarios.  Consequently, since every time a JFileChooser is used, a hidden object - a FileFilter - is used also. This FileFilter is responsible for deciding which files are to be shown in the UI. Therefore, this article will show you how to create your own FileFilters.
 
Adding a Custom File Filter.
Custom File Filtering: Using Anonymous FileFilter Implementation.
Custom File Filtering: Using Named FileFilter Implementation.
Wrapping Things Up.

PRE-REQUISITES

This article is for beginner Java programmers, so don't worry as the only pre-requisites are the Java Developer's Kit (JDK), version 1.2 or higher, and a development tool of your choice.  Although, notepad is good enough, I would recommend an Integrated Development Environment (IDE) such as NetBeans or Eclipse to ease the trivial tasks of compilation and to provide niceties like color-coded syntax.  For a balance between color-coding and the purity of using notepad, TextPad or NotePad++ would be a nice alternative on Windows.  Downloads for some editors will be listed at the end of the article; however, please feel free to use whichever tools you are comfortable with.

 

1. Adding a Custom File Filter.


To begin our journey, we will examine the basics of properly adding a FileFilter to JFileChooser.
 
JFileChooser chooser = new JFileChooser();

// using in-line definition (anonymous) implementation.
chooser.addChoosableFileFilter(new FileFilter() {

    @Override
    public boolean accept(File arg0) {
        return true;
    }

    @Override
    public String getDescription() {
        return null;
    }
    
});

// using a pre-defined (named) class implementation.
chooser.addChoosableFileFilter(
   new SomeCustomFileFilter()
);

Open in new window

As shown in the code above, the key method is addChoosableFileFilter(javax.swing.filechooser.FileFilter).  How we construct the FileFilter is a matter of implementation choice; however, accept(java.io.File) and getDescription() are always required to be implemented.  The former should return true if the file meets the filter criteria, while the latter is the description that is shown in the "Files of type:" drop-down list.

Another key to truly having a custom file filter is to turn off the standard "All Files" files of type choice:
chooser.setAcceptAllFileFilterUsed(false);

Open in new window

 

2. Custom File Filtering: Using Anonymous FileFilter Implementation.


Now let's take a look at a very simplified example using rich text format (RTF) file filter.

We'll start with the getDescription() since it doesn't take much to create:
 
public String getDescription() {
    return "*.RTF";
}

Open in new window

Tired yet!

That was a lot of code, I know. :)

So considering that should be self explanatory, let's add our accept(File) method:
 
public boolean accept(File f) {

    // Allow directories to be seen.
    if (f.isDirectory()) return true;
    
    // Allows files with .rtf extension to be seen.
    if(f.getName().toLowerCase().endsWith(".rtf"))
        return true;

    // Otherwise file is not shown.
    return false;
}

Open in new window

Voilà !

Not much harder, but a little more to talk about here.

When choosing a file, we want to be able to browse directories in order to traverse them; therefore, we have to ensure that we return true for all folders.

Then for files, we are going to do our filtering based on simple inspection of the file extension.  This is obviously not sufficient all the time especially when programming for systems that may not use file extensions in the same way Windows does (e.g., Macs at least the older ones I have dealt with used resource and data forks and did not require an extension in the filename).  However, we will stick with this example as it is very straight-forward.

Since Java is case-sensitive, for our simple test, we have to get lower case version of file name and check if it ends with desired extension (also in lower case).
 
f.getName().toLowerCase().endsWith(".rtf")

Open in new window


As an alternative, we could also parse the file extension from f.getName(), store it in a variable called "fileext" for example, and then utilize the String object's equalsIgnoreCase() method.
 
".rtf".equalsIgnoreCase(fileext)

Open in new window


Checkpoint: write your own program using JFileChooser and an anonymous implementation of FileFilter.  An example is attached for your reference, but challenge yourself before taking a look.

Challenge: can you alter your program to only allow ".rtf" files that begin with the word "article"?
 

3. Custom File Filtering: Using Named FileFilter Implementation.


Let's take this a little further; we will now add more multiple options to the "Files of type:" drop-down list.  Expanding on our simple anonymous class for filtering files based on the extension, we will now create a named implementation of javax.swing.filechooser.FileFilter.  To keep things simple, the below is an example of a nested class that could reside in the same compilation unit we created above (e.g., see FileChooserExample.java in the Appendix A).

Extending FileFilter
 
/**
 * Inherited FileFilter class to facilitate reuse when
 * multiple file filter selections are required. For example
 * purposes, I used a static nested class, which is defined
 * as below as a member of our original FileChooserExample
 * class.
 */
static class ExtensionFileFilter 
    extends javax.swing.filechooser.FileFilter {

    private java.util.List<String> extensions;
    private String description;

    public ExtensionFileFilter(String[] exts, String desc) {
        if (exts != null) {
            extensions = new java.util.ArrayList<String>();

            for (String ext : exts) {

                // Clean array of extensions to remove "."
                // and transform to lowercase.
                extensions.add(
                    ext.replace(".", "").trim().toLowerCase()
                );
            }
        } // No else need; null extensions handled below.

        // Using inline if syntax, use input from desc or use
        // a default value.
        // Wrap with an if statement to default as well as
        // avoid NullPointerException when using trim().
        description = (desc != null) ? desc.trim() : "Custom File List";
    }

    // Handles which files are allowed by filter.
    @Override
    public boolean accept(File f) {
    
        // Allow directories to be seen.
        if (f.isDirectory()) return true;

        // exit if no extensions exist.
        if (extensions == null) return false;
		
        // Allows files with extensions specified to be seen.
        for (String ext : extensions) {
            if (f.getName().toLowerCase().endsWith("." + ext))
                return true;
        }

        // Otherwise file is not shown.
        return false;
    }

    // 'Files of Type' description
    @Override
    public String getDescription() {
        return description;
    }
}

Open in new window


As you can see, the logic of the FileFilter has been changed to be more dynamic/generic to allow for re-use; however, a lot of the basics hold true.

Using our Custom FileFilter
Now, let's use our named class, taking advantage of the re-usability by adding more than filter with differing number of extensions to the same file chooser:
 
public static void main(String[] args) {
    // Instantiate the javax.swing.JFileChooser object.
    JFileChooser chooser = new JFileChooser();

    // Add file filter to the chooser object,
    // using custom implementation of abstract
    // javax.swing.filechooser.FileFilter.
    chooser
            .addChoosableFileFilter(new ExtensionFileFilter(
                    new String[] { ".DOC", ".RTF", ".TXT" },
                    "Text Documents (*.DOC|RTF|TXT)"));

    // Add second file filter to the chooser object,
    // using our same implementation class with different
    // constructor parameters.
    chooser
            .addChoosableFileFilter(new ExtensionFileFilter(
                    new String[] { ".CSV" },
                    "Comma Delimited File (*.CSV)"));

    // Verify errant inputs are handled correctly.
    chooser
            .addChoosableFileFilter(new ExtensionFileFilter(
                    null, null));

    // Turn off 'All Files' capability of file chooser,
    // so only our custom filter is used.
    chooser.setAcceptAllFileFilterUsed(false);

    chooser.showSaveDialog(null);
}

Open in new window

That's it!

Run this code and you will see how the multiple filters are listed in the "Files of type:" drop-down list and how the files available for selection change as you choose different options from the drop-down.

Checkpoint: modify your program to use your own custom class that extends FileFilter, playing with more complex criteria.  An example code snippet is below for your reference.

Challenge: can you alter your program to add a filter that will only accept PDF files smaller than 500 KB?
 

4. Wrapping Things Up.


For purposes of our test, save dialog was utilized but file dialogs can be used in other ways as well.

This will present a file dialog for an input file (to be opened):
 
chooser.showOpenDialog(null);

Open in new window


Show a custom file dialog with approval command denoted by second parameter:
 
chooser.showDialog(null, "Custom Approve Button Text");

Open in new window


For all the file dialogs, we used a first parameter of null.  This is the parent component of the file dialog; however, this can be null as shown if you just want to spawn the file dialog from an application that isn't all GUI based like we had above.

Moreover, there are easy ways to set the folder in which the file chooser starts your user when prompted to select file.

For this information and more complex/complete examples of using File Choosers in Java, see the reference link to online tutorial provided by Sun.  You will find some additional references below that may be very useful, so please read and enjoy.


SUMMARY

In conclusion, file choosers are very useful to have in Swing/GUI based applications and even more so with the ability to customize the file filter(s) associated.  The goal of this article was to demonstrate the ways of implementing this, so it is my sincere hope that it has been successful for that purpose and that you have fun coding away your own custom file filtering.

Lastly, special thanks to Venabili who graciously collaborated on the direction and wording of this article!

Happy coding!

Best regards,


Kevin (aka MWVisa1)


Appendix A: Anonymous File Filter Example.
 
//FileChooserExample.java
package com.experts_exchange;

import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

/**
 * Example of using file filter(s) with JFileChooser to limit files to specific
 * extension(s).
 * 
 * @author mwvisa1
 */
public class FileChooserExample {

    /**
     * @param args
     *            the command line arguments
     */
    public static void main(String[] args) {

        // Instantiate the javax.swing.JFileChooser object.
        JFileChooser chooser = new JFileChooser();

        // Add file filter to the chooser object,
        // using anonymous implementation of abstract
        // javax.swing.filechooser.FileFilter.
        chooser.addChoosableFileFilter(new FileFilter() {

            // Handles which files are allowed by filter.
            @Override
            public boolean accept(File f) {
                
                // Allow directories to be seen.
                if (f.isDirectory()) return true;

                // Allows files with .rtf extension to be seen.
                if (f.getName().toLowerCase().endsWith(".rtf"))
                    return true;

                // Otherwise file is not shown.
                return false;
            }

            // 'Files of Type' description
            @Override
            public String getDescription() {
                return "*.RTF";
            }
        });

        // Turn off 'All Files' capability of file chooser,
        // so only our custom filter is used.
        chooser.setAcceptAllFileFilterUsed(false);

        // Where null would be replaced by parent Component.
        chooser.showSaveDialog(null);
    }
}

Open in new window



Appendix B: Final Solution.FileChooserExample.txt


Downloads

Download JDK and/or NetBeans IDE
http://www.netbeans.org/downloads/index.html
or
http://www.sun.com/download/index.jsp

Download Eclipse IDE
http://www.eclipse.org/downloads/

Download TextPad
http://www.textpad.com/download/index.html

Download NotePad++
http://notepad-plus.sourceforge.net/uk/site.htm


References:

How To Use File Choosers
http://java.sun.com/docs/books/tutorial/uiswing/components/filechooser.html

Java Tip 85: Fun and games with JFileChooser
http://www.javaworld.com/javaworld/javatips/jw-javatip85.html

Nested Classes
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
 
4
Comment
Author:Kevin Cross
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 

Expert Comment

by:Omer-Pitou
Hi,
Thanks for the article.
What if we want to filter based on 3 extensions *.xlsx, *.xls, *.csv

Regards
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Join & Write a Comment

Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
Suggested Courses

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month