I have a JFileChooser and I need to programmatically set its currentDirectory to a network host containing several SMB shares (e.g. \\blah
). Technically this is not a "directory" but rather a shell folder representing a list of available shares.
JFileChooser has no problems navigating to a specific share (e.g. \\blah\someShare
) but cannot handle the host "directory" itself (e.g. \\blah
).
Users can navigate to such "directories" inside JFileChooser by going via "Network" shell folder, or by finding a specific share and navigating to its parent directory. Debugging shows that under-the-hood this directory is represented as a Win32ShellFolder2
. All my attempts to set currentDirectory programmatically have failed so far.
new File("\\\\blah")
can be created, but does not actually exist from Java's perspective.
chooser.setCurrentDirectory(new File("\\\\blah"));
Fails because JFileChooser
checks if the given directory exists, and new File("\\\\blah").exists()
returns false.
File dir = new File("\\\\blah").getCanonicalFile();
Fails with an exception:
java.io.IOException: Invalid argument
at java.io.WinNTFileSystem.canonicalize0(Native Method)
at java.io.WinNTFileSystem.canonicalize(WinNTFileSystem.java:428)
at java.io.File.getCanonicalPath(File.java:618)
at java.io.File.getCanonicalFile(File.java:643)
File dir = ShellFolder.getShellFolder(new File("\\\\blah"));
Fails with an exception:
java.io.FileNotFoundException
at sun.awt.shell.ShellFolder.getShellFolder(ShellFolder.java:247)
File dir = new Win32ShellFolderManager2().createShellFolder(new File("\\\\blah"));
Fails with an exception:
java.io.FileNotFoundException: File \\blah not found
at sun.awt.shell.Win32ShellFolderManager2.createShellFolder(Win32ShellFolderManager2.java:80)
at sun.awt.shell.Win32ShellFolderManager2.createShellFolder(Win32ShellFolderManager2.java:64)
Path dir = Paths.get("\\\\blah");
Fails with an exception:
java.nio.file.InvalidPathException: UNC path is missing sharename: \\blah
at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:118)
at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
at java.nio.file.Paths.get(Paths.java:84)
JFileChooser. setMultiSelectionEnabled(true) − To enable the multiple selection of file.
JFileChooser is a part of java Swing package. The java Swing package is part of JavaTM Foundation Classes(JFC) . JFC contains many features that help in building graphical user interface in java . Java Swing provides components such as buttons, panels, dialogs, etc .
Once upon a time I have faced such a task and I can say it was really annoying. First it sounds so easy, but when you start digging and trying, more and more problems show up. I want to talk about my journey.
From what I have understood, the thing here is that \\ComputerName\
is not a real place to be in the filesystem. It is an abstaction layer which content depends on your authentication credentials. And it is for windows machines only so going there would break Java's law of system independency. Summerizing it up it is nothing a File
object could point to.
You can use the Samba library jcifs but in their implementation the class SmbFile
needs user authentication and is not compatible with java File
class. So you can't use it with jFileChooser
. And sadly they are not interessted in changing it as you can read here.
I tried myself to develop a File wrapper that acts as a hybrid for File
and SmbFile
Class. But I gave it up since it brought me nightmares.
Then I had the idea of writing a simple Dialog that lists the network shares previously scaned with jcifs
and let the user choose one of them. Then a jFileChooser
with the selected share should show up.
While I implemented this idea the super simple solution to the whole problem kicked me in the butt.
Since it is absolutely no problem to point to \\ComputerName\ShareName
and click the One level higher
Button it must be possible to reproduce this step. And it is. Actually while looking under the hood of jFileChooser
I learned that places like MyComputer
or Network
are ShellFolders
which are special cases of File
Objects. But these Shell Folders are protected and not Part of the Java API.
So I could not instantiate these directly. But I could access the FileSystemView
that handles the system dependent view on the file system like creating these Shell Folders for the special locations.
So long text for a short answer. If you know one Sharename, create a File to this share name. Then use FileSystemView
to get its Parent File. And voila you can use the resulting File
object which extends a ShellFolder
with
jFileChooser
.
File f = new File("\\\\ComputerName\\ShareFolder");
FileSystemView fsv = FileSystemView.getFileSystemView();
f = fsv.getParentDirectory(f);
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(f);
One last note: This solution will not ask you for login information. So getting access to the shares must have been in Windows before using them here.
EDIT: Sorry for the long text. New Year's Eve and I was drunk. Now I want to add that I discovered the other way round.
FileSystemView fsv = FileSystemView.getFileSystemView();
File Desktop = fsv.getRoots()[0];
On Windows Systems this should give you the Desktop Folder. And if you list all the Files here:
for(File file : Desktop.listFiles())
System.out.println(file.getName());
You will notice some Entries with strange names:
::{20D04FE0-3AEA-1069-A2D8-08002B30309D} // My Computer
::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C} // Network
::{031E4825-7B94-4DC3-B131-E946B44C8DD5} // User Directory
I don't know if these codes are the same for all Windows Versions but it seems that they are for Windows7. So you can use this to get the Network Shell Folder and after that the Computer with the shares.
File Network = fsv.getChild(Desktop, "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}");
File Host = fsv.getChild(Network, "COMPUTERNAME"); // Must be in Capital Letters
The problem here is that this will take about 10 seconds because the Network Folder is scanned for content.
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