-2

Hi im working in a java project and i wanted to create a JFileChooser which i have but i want to choose only in one directory like i have the directory called "Saves" and i want the person who open the JFileChooser can only access txt inside the directory call "Saves". They cant acess anything else only the directory i set.

I wanted to only access txt and cant acess neither another directorys neither other paths

I researched a lot but i couldn't find anything. If you know about something else like another choose please help me! Thank you.

Ak-Mo
  • 389
  • 1
  • 4
  • 18

1 Answers1

5

A custom FileSystemView can be used to tweak what the user can see and where they can navigate. For example, this is a simple implementation that pretends that the passed-in directory is the root (and home) directory and has no parent (note that the majority of the methods just delegate to the system file system view):

public class RestrictedFileSystemView extends FileSystemView {
  private final FileSystemView delegate;
  private final File baseDirectory;

  RestrictedFileSystemView(File baseDirectory) {
    this.baseDirectory = baseDirectory;
    this.delegate = FileSystemView.getFileSystemView();
  }


  @Override
  public File[] getRoots() {
    return new File[] { baseDirectory };
  }

  @Override
  public File getHomeDirectory() {
    return baseDirectory;
  }

  @Override
  public File getDefaultDirectory() {
    return baseDirectory;
  }

  @Override
  public File getParentDirectory(File dir) {
    if (dir.equals(baseDirectory)) {
      return null;
    }
    return delegate.getParentDirectory(dir);
  }

  @Override
  public boolean isRoot(File f) {
    return f.equals(baseDirectory);
  }

  // all methods below here just delegate
  
  @Override
  public Boolean isTraversable(File f) {
    return delegate.isTraversable(f);
  }

  @Override
  public String getSystemDisplayName(File f) {
    return delegate.getSystemDisplayName(f);
  }

  @Override
  public String getSystemTypeDescription(File f) {
    return delegate.getSystemTypeDescription(f);
  }

  @Override
  public Icon getSystemIcon(File f) {
    return delegate.getSystemIcon(f);
  }

  @Override
  public Icon getSystemIcon(File f, int width, int height) {
    return delegate.getSystemIcon(f, width, height);
  }

  @Override
  public boolean isParent(File folder, File file) {
    return delegate.isParent(folder, file);
  }

  @Override
  public File getChild(File parent, String fileName) {
    return delegate.getChild(parent, fileName);
  }

  @Override
  public boolean isFileSystem(File f) {
    return delegate.isFileSystem(f);
  }

  @Override
  public boolean isHiddenFile(File f) {
    return delegate.isHiddenFile(f);
  }

  @Override
  public boolean isFileSystemRoot(File dir) {
    return delegate.isFileSystemRoot(dir);
  }

  @Override
  public boolean isDrive(File dir) {
    return delegate.isDrive(dir);
  }

  @Override
  public boolean isFloppyDrive(File dir) {
    return delegate.isFloppyDrive(dir);
  }

  @Override
  public boolean isComputerNode(File dir) {
    return delegate.isComputerNode(dir);
  }

  @Override
  public File createFileObject(File dir, String filename) {
    return delegate.createFileObject(dir, filename);
  }

  @Override
  public File createFileObject(String path) {
    return delegate.createFileObject(path);
  }

  @Override
  public File[] getFiles(File dir, boolean useFileHiding) {
    return delegate.getFiles(dir, useFileHiding);
  }

  @Override
  public File[] getChooserComboBoxFiles() {
    return delegate.getChooserComboBoxFiles();
  }

  @Override
  public boolean isLink(File file) {
    return delegate.isLink(file);
  }

  @Override
  public File getLinkLocation(File file) throws FileNotFoundException {
    return delegate.getLinkLocation(file);
  }

  @Override
  public File createNewFolder(File containingDir) throws IOException {
    return delegate.createNewFolder(containingDir);
  }
}

(Only tested quickly on Linux, other OS might require additional changes to some overrides).

Note that you can further restrict what directories the user can visit by overriding isTraversable() and even restrict what they see by overriding getFiles().

You can use this custom file system view in your JFileChooser like this:

FileSystemView fsv = new RestrictedFileSystemView(someBaseDirectory);
JFileChooser jfc = new JFileChooser(fsv);
jfc.showOpenDialog(parentComponent);
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • nice :) just noticed that the base itself has to be always traversable (otherwise we get an NPE) – kleopatra Mar 29 '23 at 15:10
  • 2
    @kleopatra: yeah, `FileSystemView` isn't especially well documented. It almost feels like they just exposed an internal implementation detail. There's certainly a few corner cases that you have to keep in mind and/or find out during testing. – Joachim Sauer Mar 29 '23 at 15:14
  • agree - it very much looks like ad-hoc api ;) – kleopatra Mar 30 '23 at 11:06
  • i did try using your code but didnt work on eclipse... also i really wanted to use JFileChooser... is there any chances to use it? – Tiago Martins Mar 30 '23 at 11:06
  • First: you need to be more explicit what you mean by "didn't work"? What kind of error message or problematic behaviour did you get? Second: ... this is using `JFileChooser`, I don't know why you keep saying "you want to use it", when this actively makes use of `JFileChooser`. You simply hand it another component to modify how it views the file systsem (a file-system-view if you like). – Joachim Sauer Mar 30 '23 at 11:34