GOXR3PLUS
GOXR3PLUS

Reputation: 7255

Open a File in default File explorer and highlight it using JavaFX or plain Java

I wish to do what the title says.


Part Solution:

For example in Windows you can use the code below to open a file in the default explorer and highlight it.

(although it needs modification for files containing spaces):

/**
 * Opens the file with the System default file explorer.
 *
 * @param path the path
 */
public static void openFileLocation(String path) {
    if (InfoTool.osName.toLowerCase().contains("win")) {
        try {
            Runtime.getRuntime().exec("explorer.exe /select," + path);
        } catch (IOException ex) {
            Main.logger.log(Level.WARNING, ex.getMessage(), ex);
        }
    }
}

Useful Links:

Links which are similar but no way dublicates or not answered:

How to use java code to open Windows file explorer and highlight the specified file?

Open a folder in explorer using Java

How can I open the default system browser from a java fx application?


More explanation:


Finally:

It is very strange that for so common things i can't find answers and libraries .


Example of highlighted or selected in Windows 10:

enter image description here

Upvotes: 7

Views: 7908

Answers (4)

rednoah
rednoah

Reputation: 1082

As of Java 17 the Desktop::browseFileDirectory method is still not supported on Windows 10 or later.

The historic reason is that Apple originally implemented these native Desktop integration features for Mac OS X in the com.apple.eawt package back when Apple itself was still maintaining the JDK for Mac OS X. All of that was ported into java.awt.Desktop for Java 9 as per JEP 272: Platform-Specific Desktop Features and so I guess some of these features are still only implemented for Mac OS X to this day.

Fortunately, Windows 10 does have a SHOpenFolderAndSelectItems function that we can call via JNA like so:

public interface Shell32 extends com.sun.jna.platform.win32.Shell32 {
    Shell32 INSTANCE = Native.load("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS);

    HRESULT SHParseDisplayName(WString pszName, Pointer pbc, PointerByReference ppidl, WinDef.ULONG sfgaoIn, Pointer psfgaoOut);
    HRESULT SHOpenFolderAndSelectItems(Pointer pidlFolder, WinDef.UINT cidl, Pointer apidl, WinDef.DWORD dwFlags);
}
public class Shell32Util extends com.sun.jna.platform.win32.Shell32Util {

    public static Pointer SHParseDisplayName(File file) {
        try {
            PointerByReference ppidl = new PointerByReference();

            // canonicalize file path for Win32 API
            HRESULT hres = Shell32.INSTANCE.SHParseDisplayName(new WString(file.getCanonicalPath()), null, ppidl, new WinDef.ULONG(0), null);
            if (W32Errors.FAILED(hres)) {
                throw new Win32Exception(hres);
            }

            return ppidl.getValue();
        } catch (Exception e) {
            throw new InvalidPathException(file.getPath(), e.getMessage());
        }
    }

    public static void SHOpenFolderAndSelectItems(File file) {
        Pointer pidlFolder = SHParseDisplayName(file);

        try {
            HRESULT hres = Shell32.INSTANCE.SHOpenFolderAndSelectItems(pidlFolder, new WinDef.UINT(0), null, new WinDef.DWORD(0));
            if (W32Errors.FAILED(hres)) {
                throw new Win32Exception(hres);
            }
        } catch (Exception e) {
            throw new InvalidPathException(file.getPath(), e.getMessage());
        }
    }

}

Upvotes: 1

远星河
远星河

Reputation: 139

Windows

Runtime.getRuntime().exec("explorer /select, <file path>")

Linux

Runtime.getRuntime().exec("xdg-open <file path>");

MacOS

Runtime.getRuntime().exec("open -R <file path>");

Upvotes: 4

bichoFlyer
bichoFlyer

Reputation: 198

Since Java 9 it's possible with the new method browseFileDirectory, so your method would state:

import java.awt.Desktop;
import java.io.File;
...

/**
 * Opens the file with the System default file explorer.
 *
 * @param path the path
 */
public static void openFileLocation(String path) {
    Desktop.getDesktop().browseFileDirectory(new File(path));
}

For more information, refer to the javadoc: https://docs.oracle.com/javase/10/docs/api/java/awt/Desktop.html#browseFileDirectory(java.io.File)

Upvotes: 4

alexcode
alexcode

Reputation: 19

The following is a partial answer showing you how to open the system folder you desire, but not how to highlight a specific file since I do not believe it is possible to highlight a file in a system folder, because that is probably a system OS function that cannot be accessed by Java.

This is written in Javafx code

In your Main class make a variable for Hostservices. Note that "yourFileLocation" is the address of the folder to the file, and SettsBtn is a button that exists somewhere which the user clicks to execute the code:

public class Main extends Application{

    static HostServices Host; //<-- sort of a global variable

    //some code here to make your GUI

    public Main() {
        //more code here to initialize things
    }

    public void start(Stage primaryStage) throws Exception {
        //some code here to set the stage

        //This code here opens the file explorer
        SettsBtn.setOnMouseClicked(e-> {
            Path partPath = Paths.get("yourFileLocation");
            Host = getHostServices();
            Host.showDocument(partPath.toUri().toString());
        });
    }
}

Note that you could directly open the file by making a string to the file location and the file name with its extension, such as:

Path partPath = Paths.get("yourFileLocation"+"\\"+"yourFileName.ext");

Upvotes: 1

Related Questions