Open External Application From JavaFX

后端 未结 3 1941
情深已故
情深已故 2021-01-13 20:11

I found a way to open a link on default browser using HostServices.

getHostServices().showDocument(\"http://www.google.com\");
  • Is the
3条回答
  •  無奈伤痛
    2021-01-13 20:52

    Only the solution with java.awt.Desktop worked for me to open a file from JavaFX.

    However, at first, my application got stuck and I had to figure out that it is necessary to call Desktop#open(File file) from a new thread. Calling the method from the current thread or the JavaFX application thread Platform#runLater(Runnable runnable) resulted in the application to hang indefinitely without an exception being thrown.

    This is a small sample JavaFX application with the working file open solution:

    import java.awt.Desktop;
    import java.io.File;
    import java.io.IOException;
    
    import javafx.application.Application;
    import javafx.concurrent.Task;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.stage.FileChooser;
    import javafx.stage.Stage;
    
    public class FileOpenDemo extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            final Button button = new Button("Open file");
    
            button.setOnAction(event -> {
                final FileChooser fileChooser = new FileChooser();
                final File file = fileChooser.showOpenDialog(primaryStage.getOwner());
    
                if (file == null)
                    return;
    
                System.out.println("File selected: " + file.getName());
    
                if (!Desktop.isDesktopSupported()) {
                    System.out.println("Desktop not supported");
                    return;
                }
    
                if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
                    System.out.println("File opening not supported");
                    return;
                }
    
                final Task task = new Task() {
                    @Override
                    public Void call() throws Exception {
                        try {
                            Desktop.getDesktop().open(file);
                        } catch (IOException e) {
                            System.err.println(e.toString());
                        }
                        return null;
                    }
                };
    
                final Thread thread = new Thread(task);
                thread.setDaemon(true);
                thread.start();
            });
    
            primaryStage.setScene(new Scene(button));
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    The other proposed solution with javafx.application.HostServices did not work at all. I am using OpenJFX 8u141 on Ubuntu 17.10 amd64 and I got the following exception when invoking HostServices#showDocument(String uri):

    java.lang.ClassNotFoundException: com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory

    Obviously, JavaFX HostServices is not yet properly implemented on all platforms. On this topic see also: https://github.com/Qabel/qabel-desktop/issues/420

提交回复
热议问题