通过双击文件将参数传递给 JavaFx 应用程序

Pass Parameters to JavaFx Application by double-click on file

我创建了一个 JavaFX 应用程序,部署了 .app 文件,它工作正常。然后我将操作系统设置为使用我的应用程序打开所有具有特定扩展名的文件。我的问题是,当我双击一个文件时,我的应用程序打开了,但我不知道打开它的是哪个文件。

我尝试使用函数 getParameters().getRaw() 检查应用程序参数,但它总是 returns 一个空列表。

有人知道如何检索打开应用程序的文件的路径吗?

我终于找到了解决这个问题的方法。

为了回答这个问题,我创建了一个由三个 classes 组成的示例应用程序:

Launcher
MyApp
Handler_OpenFile

MyApp 是 class 扩展 javafx.application.Application class,Handler_OpenFile 用于处理双击事件,最后 Launcher 是包含主.

Launcher.java:这个 class 必须存在,因为如果在扩展 javafx.application.Application 的 class 中定义了 main,则 OpenFilesEvent 将无法正常工作(更准确地说仅当应用程序已打开时才会触发 OpenFilesEvent。

public class Launcher {
    public static void main(String[] args) {
        if (System.getProperty("os.name").contains("OS X")){
            com.apple.eawt.Application a = com.apple.eawt.Application.getApplication();
            Handler_OpenFile h_open = new Handler_OpenFile();
            a.setOpenFileHandler(h_open);
            Application.launch(Main.class, args);
        }
    }
}

Handler_OpenFile.java:这个class定义了一个静态变量,存储了打开应用程序的File的值。这可能不是最好的解决方案,但它是我现在可以让它工作的唯一方法。

public class Handler_OpenFile implements OpenFilesHandler {
    public static File file = null;

    @Override
    public void openFiles(OpenFilesEvent e) {
        for (File file : e.getFiles()){
            this.file = file;      
        }
    }
}

MyApp.java: 这个 class 将能够访问在 Handler_OpenFile class 中分配的静态值并检索打开文件的绝对路径。

public class MyApp extends Application {
    @Override
    public void start(Stage primaryStage) {

        Logger logger = Logger.getLogger("log");  
        FileHandler fh;  

        try {  
            // This block configure the logger with handler and formatter  
            fh = new FileHandler("../Logfile.log");  
            logger.addHandler(fh);
            SimpleFormatter formatter = new SimpleFormatter();  
            fh.setFormatter(formatter);  

            // the following statement is used to log any messages  
            logger.info("Application launched from: " + Handler_OpenFile.file.getAbsolutePath());  

        } catch (SecurityException | IOException exception) {  
            exception.printStackTrace();  
        } 


        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,400,400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

最后,在创建捆绑包的 build.xml 文件中,您必须添加文件关联(在此示例中,文件的扩展名为 .zzz):

<fx:info title="Sample" vendor="me">
    <fx:association extension="zzz" description="Sample Source"/>
</fx:info>

这仅适用于 Java(8u40) 的最后更新:documentation at this link. For previous versions you will have to change the info.plist manually inside your bundle like it is said in the Apple Java Extensions documentation.

我在 OS X 上遇到同样的问题已经有一段时间了,接受的答案对我不起作用。经过大量谷歌搜索,我终于在 http://permalink.gmane.org/gmane.comp.java.openjdk.openjfx.devel/10370.

找到了解决方案

总而言之,我需要使用 com.sun API 才能使其正常工作。我在下面包含了一些示例代码:

public class MyApp extends Application {
    public MyApp() {
        com.sun.glass.ui.Application glassApp = com.sun.glass.ui.Application.GetApplication();
        glassApp.setEventHandler(new com.sun.glass.ui.Application.EventHandler() {
            @Override
            public void handleOpenFilesAction(com.sun.glass.ui.Application app, long time, String[] filenames) {
                super.handleOpenFilesAction(app, time, filenames);
                // Do what ever you need to open your files here
            }
        });
    }

    // Standard JavaFX initialisation follows
}

在实施适当的 API 来处理文件打开之前,这应该被视为临时解决方案。希望这个答案可以帮助那些无法获得公认答案的人。

注意:Java不是我经常使用的语言(我的应用程序使用 Scala 和 ScalaFX),因此对于代码中的任何语法错误,我深表歉意。