JavaFX2 - option for starting application without

2019-07-15 06:23发布

问题:

I'm developing JavaFx application that will be run under Linux, both in environments that support GUI and environments that do not support GUI. Meaning, if I connect to machine where application will be run with "ssh -X" when application is started GUI should open, and if I connect using just "ssh" (without -X) then console version of application should start.

How can I achieve this when using JavaFx?

I tried it in the following way:

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);
        }
    }
}

But it didn't work, and when I tried to connect via SSH to another machine without -X option, I still receive error:

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

I also noticed if I run application in environment with GUI, giving "nogui" command line option, I would receive printout "NOGUI SELECTED", but application would not end it's execution instead it would just hang there.

Can you help me how I can achieve this?

回答1:

I am not sure what exactly is causing this issue that you are facing. But JavaFX is known to have thread issues, this could be related to JavaFX Main Class spawning child thread(s). But I am not knowledgeable enough to answer that.

But what I can do is, provide an alternative, if you are looking for one. You can create a separate class (Not extending Application class) with the main method and then call the Main class if required from there, this way your application will exit if nogui is passed.

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);
        }
    }
}

If you don't wish to pass arguments, then you can simply use Main.launch(Main.class) instead of Main.launch(Main.class, args). I have not tested this out, but it should work.



回答2:

Quoting an answer from elsewhere that worked for me with javafx as root on Ubuntu ... Maybe this can help someone else. I had the same question as you but for a normal user. Let's say I want to start firefox using the user account foo. I'm logged in as bar:

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

Sadly that command failed with the same error as in the question (i.e. no protocol specified & cannot open display)

My solution was to simply add the user foo to the list of authorised access to the X server.

xhost si:localuser:foo

And that was it, I was then able to launch Firefox (and other X application) using sudo and the user foo.



标签: javafx-2