8u40 has javapackager improvements to help you do file associations in your
installers. I'm looking forward to this, though for now I have to do it
manually with 8u20.

But one problem I've found is that just setting up the file associations is
not enough. You must handle the "openFile" messages sent by the OS as well.
On Linux/Windows the interface is simple: the OS starts another copy of
your app with the command line parameter. On MacOS you get a message posted
to your message queue because apps are single instance by default. To
handle this in JFX we must use internal APIs, like in the code snippet
below.

Hopefully 8u40 will contain a proper cross platform file open request API
that exposes this in a better way, otherwise the new javapackager support
will be rather hard to use.

private void handleFileOpenRequests() {
    // This is only for MacOS, where the OS single instances us by
default and sends us a message at startup to ask
    // us to open a file. It requires internal APIs.
    if (!System.getProperty("os.name").toLowerCase().contains("mac")) return;
    com.sun.glass.ui.Application app =
com.sun.glass.ui.Application.GetApplication();
    com.sun.glass.ui.Application.EventHandler old = app.getEventHandler();
    app.setEventHandler(new com.sun.glass.ui.Application.EventHandler() {
        @Override public void
handleQuitAction(com.sun.glass.ui.Application app, long time) {
            old.handleQuitAction(app, time);
        }
        @Override public boolean handleThemeChanged(String themeName) {
            return old.handleThemeChanged(themeName);
        }

        @Override
        public void handleOpenFilesAction(com.sun.glass.ui.Application
app, long time, String[] files) {
            for (String strPath : files) {
                if
(strPath.equals("com.intellij.rt.execution.application.AppMain"))
                    continue;   // Only happens in dev environment.
                log.info("OS is requesting that we open " + strPath);
                Platform.runLater(() -> {
                    Main.instance.mainWindow.handleOpenedFile(new
File(strPath));
                });
            }
        }
    });
}

Reply via email to