Is there a JavaFX way to add a file to OS recent files?

Viewed 110

I have an application that shows a JavaFX/OpenJFX FileChooser, when the user chooses a file it should appear in the OS recent files list, but it doesn't happen.

How could I create a symlink or add the file to the OS recent files?

Thanks.

1 Answers

This answer covers the Windows part so far, and hopefully, this becomes a collaborative answer and somebody else fills up the missing parts for macOS and Unix:

Main Structure:

public interface RecentDocsSaver {
    void addToRecentDocs(File file);   
}
public class RecentDocsSaverFactory {
    private static final String OS_NAME = System.getProperty("os.name").toLowerCase();

    private RecentDocsSaverFactory() {
    }

    public static RecentDocsSaver getOSInstance() {
        if (isWindows()) {
            return WindowsRecentDocsSaver.INSTANCE;
        }
        // TODO: add code for mac and unix
        throw new UnsupportedOperationException(OS_NAME + " is not supported");
    }

    private static boolean isWindows() {
        return OS_NAME.contains("win");
    }

    private static boolean isMac() {
        return OS_NAME.contains("mac");
    }

    private static boolean isUnix() {
        return OS_NAME.contains("nix") || OS_NAME.contains("nux") || OS_NAME.contains("aix");
    }
}

Windows:

I believe using JNA is the correct way to add files to Windows's recent list (other ways include accessing Windows registry).

The Shell32 library provides a function to add files directly to the recent files list. The function is SHAddToRecentDocs(flags, path).

public class WindowsRecentDocsSaver implements RecentDocsSaver {
    public static final WindowsRecentDocsSaver INSTANCE = new WindowsRecentDocsSaver();

    private WindowsRecentDocsSaver() {
    }

    public void addToRecentDocs(File file) {
        if (file != null) {
            WString unicodeStringPath = new WString(file.getPath());
            // 3 is for null-terminated Unicode string
            Shell32.INSTANCE.SHAddToRecentDocs(3, unicodeStringPath);
        }
    }

    private interface Shell32 extends ShellAPI {
        Shell32 INSTANCE = Native.loadLibrary("shell32", Shell32.class);

        void SHAddToRecentDocs(int flags, WString file);
    }
}

macOS: TODO

Unix: TODO

Usage:

File recent = fileChooser.showOpenDialog(window);
if (recent != null) {
    RecentDocsSaverFactory.getOSInstance().addToRecentDocs(recent);
}
Related