2014-04-19 18 views
16

Sto eseguendo del codice in Java su Ubuntu 12.04 LTS a 64 bit (con Gnome Shell), utilizzando Oracle JDK 1.8.0_05 tramite NetBeans8.0.JavaFX Freeze su Desktop.open (file), Desktop.browse (uri)

La seguente funzione funziona perfettamente quando richiamato nella principale o in un progetto Java altrimenti vuoto, tuttavia quando chiamato da qualsiasi applicazione JavaFX, provoca la finestra di congelare e bloccare (anche se il progetto è conforme perfettamente), obbligandola a essere chiuso a forza.

Qualcuno può suggerire eventuali problemi con quello che ho scritto che potrebbe causare un problema o un ciclo?

Purtroppo, a causa della modalità di errore, non è presente alcun messaggio di errore che possa essere fornito o analizzato.

Eventuali suggerimenti ricevuti con gratitudine, grazie in anticipo.

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 protected]")); 
      } 
      catch (URISyntaxException | IOException e){ 
       System.out.println(e); 
      } 
} 

risposta

21

Ho anche avuto lo stesso problema e questa soluzione funziona per me:

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

La parte importante qui è 'Desktop.isDesktopSupported()'. Sembra che ci sia una sorta di inizializzazione. Senza di ciò non funziona. Queste risposte dovrebbero essere contrassegnate come risposta accettata. –

+2

Ciò che ha funzionato per me è stata la creazione di un nuovo thread, che sembra essere necessario. –

+0

Sembra che "Desktop.open()" abbia lo stesso problema e soluzione. Grazie, Alex :). – jamie

2

ho anche questo stesso problema. Ho scoperto che se chiamo il metodo Desktop.open() da un nuovo thread, il file si aprirà dopo Chiudo la finestra dell'applicazione JavaFX, ma questo non aiuta molto.

Se mettete

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

al tuo metodo principale dopo vostro lancio (args) chiamata, anche i non ottenere chiamato fino a quando dopo aver chiuso l'applicazione JavaFX.

Sembra che ci sia un qualche tipo di problema di concorrenza tra l'applicazione JavaFX e Swing.

Su Ubuntu si può provare

xdg-open filename 

dal JavaFX app.

Per quanto posso dire, il codice deve essere attivo.

+0

Grazie per questo, bello sapere che non sto diventando matto - I kno w su xdg-open e funziona bene, ma sto usando solo Java per garantire una facile operatività cross-platform ... Ma sta cadendo in modo piuttosto piatto sul momento - posso chiedere che ambiente stai correndo? Grazie! – Wren

1

C'è un nuovo modo di gestire questo in JavaFX. L'unico lato negativo che vedo è che è necessario creare un'istanza di HostServicesDelegate utilizzando il singleton Application.

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

L'utilizzo di API 'com.sun' come' com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory' è sconsigliabile in quanto non è garantito che sia disponibile nelle future versioni di JavaFX. Utilizzare invece l'API pubblica ['Application :: getHostServices()'] (https://docs.oracle.com/javase/8/javafx/api/javafx/application/Application.html#getHostServices--). – jewelsea

3

ho risolto problema con ...

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

} 
1

incapsulare in un thread di sistema:

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()); 
+0

Potete fornire ulteriori spiegazioni? Qual è la causa del problema? Perché questa soluzione funziona? –

+0

Sono sicuro che il thread JavaFX viene bloccato con 'Destktop.getDesktop(). Browse()', ma non ne conosco il motivo. Il thread JavaFX deve essere utilizzato solo per brevi attività correlate alla vista (attiva/disattiva pulsanti, aggiungi elementi agli elenchi, cambia scheda). L'incapsulamento del comando _browse_ in un thread di sistema consentirà al thread JavaFX di continuare l'aggiornamento della vista App, mentre l'altro thread è libero di aprire il browser senza interrompere la GUI. (Ci scusiamo per la risposta in ritardo) –