7

I am creating an application in which it would be very easy for a user to actually be able to click on a link in the application, which opens up a specific folder in Finder (in Mac)/ Windows Explorer. This can happen on click event of a link or a button.

Is there a way I can open these native OS applications (for a specific folder) via Swing?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Rohan
  • 871
  • 1
  • 16
  • 32
  • *"a specific folder"* A system folder, a directory created by your app. or the app. installer, or something else? – Andrew Thompson Sep 10 '12 at 02:18
  • More importantly, what user feature does this provide? Browse the user media? Browse installed templates/plugins? Look at app. install/properties directory? .. – Andrew Thompson Sep 10 '12 at 02:25

3 Answers3

30

Short Answer:

if (Desktop.isDesktopSupported()) {
    Desktop.getDesktop().open(new File("C:\\"));
}

Long Answer: Though reading what OS it is and then running an OS specific command would work, it entails, to an extent, hard coding of what needs to be done.

Let Java handle how each OS should open directories. Shouldn't be our headache to take. <3 abstraction.

Reading the #open(File) method documentation reveals that it will open the link on all OS' which support the operation. If the current platform doesn't support opening of folders or files (say a headless environment? of course, my guess as to why it won't open is conjecture), it will throw an UnsupportedOperationException. If the user doesn't have access to read the folder (Windows Vista/7/8, Unix based machines), you will get a SecurityException. So if you ask me, it's rather well handled.

Updated: added an if check before getting the Desktop object so that your code is saved from nasty HeadlessException and UnsupportedOperationException exceptions as mentioned in the #getDesktop() Java Documentation.

javatarz
  • 1,174
  • 16
  • 30
  • 4
    +1 for easiest cross-platform solution if JRE 1.6+ is available. – trashgod Sep 09 '12 at 17:57
  • 1
    This solution saved me after many failed attempts on Apple to use `Desktop.getDesktop().browse(new File("/Users/John/Desktop").toURI());` which was working fine on Windows only. On Apple, the symptom was opening Finder to the last browsed location. Mistake on my part (improper use of "browse", so wanted to share). – tresf May 14 '15 at 02:14
  • 1
    It might be handy in some cases to check whether the desired action is supported before invocation of the `Desktop`'s methods, e.g. `Desktop.getDesktop().isSupported(Desktop.Action.OPEN)`. – Pavel Jan 11 '17 at 07:11
  • On my mac (10.12.4, java 8) `browse(uri)` and `open(file)` work only for directories. For files they throw `java.security.PrivilegedActionException`. The solution is to use native os specific way, e.g. using `open --reveal path` on Mac or using `explorer.exe /select,path` for Windows. See example at http://stackoverflow.com/a/18004334/418358 – Roman Chernyatchik Apr 19 '17 at 12:22
  • +Roman Chernyatchik Generally, I'd recommend not implementing OS specific code in your application. Java is supposed to abstract that out. If you're having to make low level calls to OS specific binaries, I'd try to look for alternatives. – javatarz Apr 23 '17 at 14:07
  • Please consider selecting this as the recommended answer. – b005t3r Apr 17 '20 at 12:18
10

Use Runtime.getRuntime().exec("command here"); to execute a command in the system on which java is running.

For explorer.exe, you can simply pass the absolute path of the folder as an argument, e.g.

Explorer.exe "C:\Program Files\Adobe"

In Mac OS X, you can use the open command:

open /users/

you can find out how to detect which OS You're on, and hence which code to run, here. For example, this will chek if you are on windows:

public static boolean isWindows() {

    String os = System.getProperty("os.name").toLowerCase();
    // windows
    return (os.indexOf("win") >= 0);

}
Jakob Weisblat
  • 7,450
  • 9
  • 37
  • 65
-1

This will get a File from the File System:

public static File selectDirectory(JFrame frame, File file, JComponent component, String title) {

    File selectedFile = null;

    if ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"
            .equalsIgnoreCase(UIManager.getSystemLookAndFeelClassName())) {
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        String absPath = file.getAbsolutePath();
        fc.setSelectedFile(new File(absPath));

        int returnVal = fc.showOpenDialog(component);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            selectedFile = fc.getSelectedFile();
        }
    } else {
        System.setProperty("apple.awt.fileDialogForDirectories", "true");

        FileDialog fd = new FileDialog(frame, title, FileDialog.LOAD);
        String absPath = file.getAbsolutePath();
        fd.setDirectory(absPath);
        fd.setFile(absPath);

        fd.setVisible(true);

        if (fd.getFile() != null) {
            String selectedFileName = fd.getDirectory() + File.separator + fd.getFile();
            selectedFile = new File(selectedFileName);
        }
    }

    return selectedFile;
}
Ironcache
  • 1,719
  • 21
  • 33