JavaFX Freeze on Desktop.open(file), Desktop.brows

2019-01-18 03:31发布

问题:

I'm running some code in Java on Ubuntu 12.04 LTS 64 Bit (with Gnome Shell), using Oracle JDK 1.8.0_05 via NetBeans8.0.

The following function works perfectly when called either in Main or in an otherwise empty Java Project, however when called from any JavaFX application, it causes the window to freeze and stop responding (although the project complies perfectly), requiring it to be Force Closed.

Can anyone suggest any issues with what I've written which might be causing an issue or loop?

Alas, due to the mode of failure, there is no error message that I can supply or analyse.

Any suggestions gratefully received, thanks in advance.

   public static void desktopTest(){

            Desktop de = Desktop.getDesktop();

            try {
                de.browse(new URI("http://stackoverflow.com"));
            }
            catch (IOException | URISyntaxException e) {
                System.out.println(e);
            }

            try {
                de.open(new File("/home/aaa/file.ext"));
            }
            catch (IOException e){
                System.out.println(e);
            }
            try {
                de.mail(new URI("mailto:email@example.com"));
            }
            catch (URISyntaxException | IOException e){
                System.out.println(e);
            }
}

回答1:

I also had the same problem and this solution works for me:

if( Desktop.isDesktopSupported() )
{
    new Thread(() -> {
           try {
               Desktop.getDesktop().browse( new URI( "http://..." ) );
           } catch (IOException | URISyntaxException e1) {
               e1.printStackTrace();
           }
       }).start();
}


回答2:

I resolved problem with...

 public static void abrirArquivo(File arquivo) {
    if (arquivo != null) {
        if (arquivo.exists()) {
            OpenFile openFile = new OpenFile(arquivo);
            Thread threadOpenFile = new Thread(openFile);
            threadOpenFile.start();
        }
    }
}

private static class OpenFile implements Runnable {

    private File arquivo;

    public OpenFile(File arquivo) {
        this.arquivo = arquivo;
    }

    private void abrirArquivo(File arquivo) throws IOException {

        if (arquivo != null) {
            java.awt.Desktop.getDesktop().open(arquivo);
        }

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            abrirArquivo(arquivo);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}


回答3:

I also have this same problem. I found out that if I call the Desktop.open() method from a new thread, the file will open after I close the JavaFX application window, but that doesn't help much.

If you put

SwingUtilities.invokeLater(() -> System.out.println("Hello world"));

in to your main method after your launch(args) call, it also won't get called until after you close the JavaFX application.

It seems like there's some kind of concurrency issue between the JavaFX application and Swing.

On Ubuntu you can try

xdg-open filename

from your JavaFX app.

As far as I can tell, your code should work.



回答4:

There is a new way to handle this in JavaFX. The only downside I see is you need to instantiate a HostServicesDelegate using the Application singleton.

HostServicesDelegate hostServices = HostServicesFactory.getInstance(appInstance);
hostServices.showDocument("http://www.google.com");


回答5:

Encapsulate it on a System thread:

    final String url = "www.google.com";
    final Hyperlink hyperlink = new Hyperlink("Click me");
        hyperlink.setOnAction(event -> new Thread(() -> {
            try {
                Desktop.getDesktop().browse(new URI(url));
            } catch (IOException | URISyntaxException e1) {
                e1.printStackTrace();
            }
        }).start());