JavaFX2 - 在没有 GUI 的情况下启动应用程序的选项

JavaFX2 - option for starting application without GUI

我正在开发将在 Linux 下 运行 的 JavaFx 应用程序,无论是在支持 GUI 的环境还是在不支持 GUI 的环境中。 意思是,如果我连接到应用程序将 运行 和 "ssh -X" 的机器,当应用程序启动时 GUI 应该打开,如果我只使用 "ssh"(没有 -X)连接,那么控制台版本应用程序应该启动。

如何在使用 JavaFx 时实现此目的?

我试过以下方法:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("MainGui.fxml"));
        SplitPane page = null;
        try {
            page = (SplitPane) loader.load();
        } catch (IOException e) {
            System.exit(1);
        }   

        Scene scene = new Scene(page);
        primaryStage.setScene(scene);
        primaryStage.setResizable(false);

        primaryStage.show();

    }

    public static void main(String[] args) {

        if (args.length == 1 && args[0].equals("nogui")) {
            System.out.println("NOGUI SELECTED");
        } else {
            launch(args);
        }
    }
}

但是它不起作用,当我尝试通过 SSH 连接到另一台没有 -X 选项的机器时,我仍然收到错误消息:

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.UnsupportedOperationException: Unable to open DISPLAY
        at com.sun.glass.ui.gtk.GtkApplication.<init>(GtkApplication.java:68)
        at com.sun.glass.ui.gtk.GtkPlatformFactory.createApplication(GtkPlatformFactory.java:41)
        at com.sun.glass.ui.Application.run(Application.java:146)
        at com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:257)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:211)
        at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:675)
        at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:337)
        at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
        ... 5 more

我还注意到,如果我 运行 在具有 GUI 的环境中应用程序,提供 "nogui" 命令行选项,我会收到打印输出 "NOGUI SELECTED",但应用程序不会结束它的执行,而是它只会挂在那里。

你能帮我实现这个目标吗?

我不确定到底是什么导致了您遇到的这个问题。但是已知 JavaFX 存在线程问题,这可能与 JavaFX Main Class 生成子线程有关。但我的知识不足以回答这个问题。

但是我可以做的是,如果您正在寻找替代方案,请提供替代方案。您可以使用 main 方法创建一个单独的 class(不扩展应用程序 class),然后根据需要从那里调用 Main class,这样您的应用程序将在 nogui通过了

public class NewMain {
    public static void main(String[] args) throws Exception {
        if (args.length == 1 && args[0].equals("nogui")) {
            System.out.println("NOGUI SELECTED");
        } else {
            Main.launch(Main.class, args);
        }
    }
}

如果您不想传递参数,那么您可以简单地使用 Main.launch(Main.class) 而不是 Main.launch(Main.class, args)。我还没有对此进行测试,但它应该可以工作。

引用来自其他地方的答案,该答案对我有用,在 Ubuntu 上以 javafx 为根...也许这可以帮助其他人。我和你有同样的问题,但对于普通用户。假设我想使用用户帐户 foo 启动 firefox。我以 bar:

身份登录

[bar@localhost ~]$ sudo -u foo -H firefox

遗憾的是,该命令失败并出现与问题中相同的错误(即未指定协议且无法打开显示)

我的解决方案是简单地将用户 foo 添加到 X 服务器的授权访问列表中。

xhost si:localuser:foo

就是这样,然后我可以使用 sudo 和用户 foo 启动 Firefox(和其他 X 应用程序)。