FilenameFilter accept method conditional problem


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 9 of 9

Thread: FilenameFilter accept method conditional problem

  1. #1
    Join Date
    Mar 2004
    Posts
    4

    Question FilenameFilter accept method conditional problem

    I am really new to Java. There are not many examples beyond the basic "hard-coded" use of the accept method filter for FilenameFilter. I can successfully use a hard coded accept method filter for extensions such as jpg, gif, etc. I am not using a filter in dialogs for file selections. This is for filtering files in a directory and returning a list of the filtered filenames for further program use.

    Here's what I would like to do. I would like the end user to pass whatever directory they desire and extensions they desire. I place this in an array in main (String[] args). args[0] is the directory (var File passedPath). Any other passed args are user defined extensions.

    The filter would then return files of their filtering choice. I have tried to use a FOR loop to walk through an array of arguments within the accept method. However, the accept method will only do the FOR loop once even though the loop counters (thru the debugger) show it should keep within the FOR loop.

    I have the accept method in a different class (ListFilter). I use it something like the following.
    FilenameFilter filter = new ListFilter();
    File[] fileList = passedPath.listFiles(filter);
    if(fileList != null) {
    List filteredList = Arrays.asList(fileList);
    Collections.sort(filteredList);
    /* return it to the user */
    }

    Are their specific limitations on conditionals such as FOR loops within the accept method of a FilenameFilter? Any better ways to do this? BTW, I am using JCreator Pro.
    Thanks

  2. #2
    Join Date
    Mar 2004
    Posts
    635
    Here's a filter I made to only get mp3 files.

    Code:
    import java.io.*;
    
    public class FilterMP3 implements FileFilter
    {
        public boolean accept(File pathname)
        {
            if (pathname.isFile())
                return pathname.getName().endsWith(".mp3");
            else
                return true;
        }
        
        public String getDescription()
        {
            return "Filters out any file without a .mp3 extension.  Folder names are not filtered.";
        }
    
    }

    You would then use it like this.

    Code:
    private FileFilter filter = new FilterMP3();
    private File f = new File(the path name);
    
    File[] d = f.listFiles(filter);

  3. #3
    Join Date
    Mar 2004
    Posts
    635
    I reread what you posted. Not sure if my above post helped any. If what you want to do is provide a way to filter files based on user preferences, I'm not sure how you could do it. I only know how to hardcode what you want to filter.

  4. #4
    Join Date
    Mar 2004
    Posts
    4
    I have no problem with your way. I can even set an array in the caller for multiple extensions and then "hard code" the reference to them in the filter (one to one with a var in accept). That just moves the problem from one place to another.

    I really need to build an array/list in the caller method of the extensions and have the accept filter parse the array of extensions when it does its filtering.

    I've searched and searched and can't find any examples or documentation for what can be done inside the accept filter other than "hard coding" the extensions for the filter.

    Since it applies to the every File/Dir at the time of .ListFiles one by one, I would assume any java coding could be done in the accept method. Evidently there are limitations and caveats I can't find examples or documentation on easily.

    Thanks for the reply though.

  5. #5
    Join Date
    Mar 2004
    Posts
    635
    accept() can do whatever you want, provided the return type is the same and the parameters are the same. Aside from that, you're free to do whatever you want really.

    Code compiles, but I haven't tested it. Have an array list of strings containing the extensions you want. Help any yet?

    Code:
    import java.io.*;
    import java.util.ArrayList;
    
    public class thing implements FileFilter
    {
        private ArrayList list = new ArrayList();
        
        public thing(ArrayList a)
        {
            list = a;
        }
        
        public boolean accept(File pathname)
        {
            String ext = null;
            if (pathname.isFile())
            {
                for (int i=0; i<list.size(); i++)
                {
                    ext = (String)list.get(i);
                    return pathname.getName().endsWith("."+ext);
                }
            }
            //return false if you dont want folders to be accepted
            return true;
        }
    }

    Code:
    private FileFilter filter = new thing(extensionList);

  6. #6
    Join Date
    Mar 2004
    Posts
    4
    This has compile problems, but the intent led me in the right direction. I have it running beautifully now. Thanks for the push in the right direction. I rewrote from scratch rather than try and "fix" my old code.
    Thanks again.

  7. #7
    Join Date
    Feb 2004
    Posts
    808
    note that scanning arrays and comparing strings is quite slow (no offence Phaelax).. heres another way that is slightly quicker:

    Code:
    import java.io.FileFilter;
    import java.util.HashMap;
    
    public class MultiFilter implements FileFilter
    {
        HashMap extFinder;
        boolean ignoreC = true;
    
        public MultiFile(String[] extensions, boolean ignoreCase){
          ignoreC = ignoreCase;
          this(extensions);
        }
    
        public MultiFile(String[] extensions){
    
          extFinder = new HashMap((int)extensions.length*2, 0.75);
    
          for(int i=0;i<extensions.length; i++){
            if(ignoreC)
              extFinder.put(extensions[i].toLowerCase(), null);
            else
              extFinder.put(extensions[i], null);
          }
        }
    
        public boolean accept(File f)
        {
            String ext = f.getName();
            if(ignoreC)
              ext = ext.substring(ext.lastIndexOf(".")).toLowerCase();
            else
              ext = ext.substring(ext.lastIndexOf("."));
    
            return extFinder.containsKey(ext);
        }
    }
    pretty, isnt it?

    now, for maximum speed, switch off case ignorance, but bear in mind that file.Mp3 will not be accepted by a file.mP3 filter.. on windows, theya re the same thing.. on unix, they ae different files anywya, and unix doesnt really use file extensions

    so.. why's this neater?

    well, a hash map is a storage device twith an incredibly fast lookup time. it also has the handy attribute that you can determine if it has a key in it.. so basically we are abusing it into being a fast lookup container, whereas it is supposed to be a container for objects that are to be retrieved by name.. but hey

    we make a new hash map relative to the size of the array (double, initially) and declare the load factor to be slightly above 0.5. what does this mean? if we pass in an array of ten items, a HashMap with 20 slots will be made. the load factor determines whether the hashmap will grow or not. ours wont, because nothing is ever added to it.. but a load factor of 75% or 0.75 means that when the map gets 75% full it will attempt to double in size to reduce the load factor. low load factor = fast lookups, but in our case, it is very unlikely that it will matter so much.. it only becomes an issue when you stuff multiple things into a hash table that use keys with equivalent magic numbers (a rare thing)

    we fill the hash map with the extensions (lowercasing them if ignorance is on) as the KEYS and nothing as the value (i would have used my favourite, a hashtable, for this, but it doesnt allow null values)
    all we are interested in is the keys.. and key lookup in a hashmap is very quick

    so the hashmap becomes filled with the extensions we want..

    it is now a simple matter to make the accept method:
    rip off the extension and ask the hashmap if it contains it or not..
    The 6th edict:
    "A thing of reference thing can hold either a null thing or a thing to any thing whose thing is assignment compatible with the thing of the thing" - ArchAngel, www.dictionary.com et al.
    JAR tutorial GridBag tutorial Inherited Shapes Inheritance? String.split(); FTP?

  8. #8
    Join Date
    Feb 2004
    Posts
    808
    or, if you always want to ignore case (smaller code)

    Code:
    import java.io.FileFilter;
    import java.util.HashMap;
    
    public class MultiFilter implements FileFilter
    {
        HashMap extFinder = new HashMap();
    
        public MultiFile(String[] extensions){
          for(int i=0;i<extensions.length; i++){
            extFinder.put(extensions[i].toLowerCase(), null);
          }
        }
    
        public boolean accept(File f)
        {
            String ext = f.getName();
              ext = ext.substring(ext.lastIndexOf(".")).toLowerCase();
            return extFinder.containsKey(ext);
        }
    }
    The 6th edict:
    "A thing of reference thing can hold either a null thing or a thing to any thing whose thing is assignment compatible with the thing of the thing" - ArchAngel, www.dictionary.com et al.
    JAR tutorial GridBag tutorial Inherited Shapes Inheritance? String.split(); FTP?

  9. #9
    Join Date
    Mar 2004
    Posts
    4
    Thanks for the hashmap info. As a newbie java user, I had seen the topic of hashmaps, but not delved into them.

    Now you've done it, I HAVE to dive into hashmaps now

    Thanks,
    This is much appreciated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center