View Full Version : [JAVA] Problema con path
Salve a tutti, ho un problema nell'aprite un file richiamato con java (Desktop).
Devo aprire un file .pdf
Vi faccio una mappa sintetica dei package
package1 (File) dentro ha questo
1. File che si chiama manuale.pdf
2. ClasseApriFile{
public static File manuale= new File((InvocaFile.class.getResource("c.pdf").getPath()));
public static void openManuale(){
try {
Desktop.getDesktop().open(manuale);
} catch (IOException ex) {}
}
}//fineclasse
package2
classe che esegue il ClasseApriFile.openManuale();
Succedono queste cose:
(con il progetto salvato nella cartella C:bla bla\ntbeans bla bla\...
1. Avvio l'applicazione e non funziona. Se stampo il path del file mi riporta
C:\Documents%20and%20Settings\nexus\Documenti\NetBeansProjects\Chat\build\classes\File\c.pdf
Negli spazi mi mette il simbolo %
2. Se sposto il progetto in un altro HD, compilo ed eseguo il programma va.
3. Se creo il .jar il file non lo apre. Ma perché?!
Usa toURI al posto di getPath. Il passaggio URL -> URI -> File dovrebbe gestire la conversione dei caratteri speciali nel percorso del file.
Non è cambiato niente. Se eseguo il programma dall'IDE funziona, lo apre. Se creo il .jar e lo eseguo non me lo apre.
public static void openManuale() throws URISyntaxException{
File f = new File(InvocaFile.class.getResource("c.pdf").toURI());
try {
Desktop.getDesktop().open(f);
} catch (IOException ex) {
Logger.getLogger(InvocaFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("File non trovato");
}
}
E' cambiato che al posto di
C:\Documents%20and%20Settings\nexus\Documenti\NetBeansProjects\Chat\build\classes\File\c.pdf
Ora avrai
C:\Documents and Settings\nexus\Documenti\NetBeansProjects\Chat\build\classes\File\c.pdf
Nota che quando impacchetti il progetto se manuale.pdf si trova dentro ad un package del progetto (file) manuale.pdf va a finire dentro al jar del programma (a meno che tu non l'abbia escluso personalizzando il task di ant).
Le risorse contenute in un jar sono accessibili tramite getResource ma NON sono file. Siccome Desktop opera sui file prima di poter aprire il manuale con il lettore pdf di sistema devi estrarre il file dal jar - magari in una cartella temporanea - oppure devi distribuire il manuale al di fuori del jar. La prima opzione è più "simpatica" perchè tiene uniti i file del programma.
E' cambiato che al posto di
C:\Documents%20and%20Settings\nexus\Documenti\NetBeansProjects\Chat\build\classes\File\c.pdf
Ora avrai
C:\Documents and Settings\nexus\Documenti\NetBeansProjects\Chat\build\classes\File\c.pdf
Si, è vero.
Nota che quando impacchetti il progetto se manuale.pdf si trova dentro ad un package del progetto (file) manuale.pdf va a finire dentro al jar del programma (a meno che tu non l'abbia escluso personalizzando il task di ant).
E qua ci sono, è dentro il .jar, come lo sono le .gif (dentro il codice, c'è un'istruzione setIcon che non da errore ma non mi mette l'icona che gli dico, non ne mette proprio, svuota il contenitore.
Le risorse contenute in un jar sono accessibili tramite getResource ma NON sono file. Siccome Desktop opera sui file prima di poter aprire il manuale con il lettore pdf di sistema devi estrarre il file dal jar - magari in una cartella temporanea -
Cioè, se clicco su apri file lui dovrebbe creare una directory e metterci dentro il pdf che è dentro al .jar? Sono confuso, non capisco perchè deve l'hanno fatto così questa cosa :D
Se per le icone hai usato ImageIcon e non vedi l'icona allora il percorso che usi per puntare all'immagine non è corretto.
Tieni conto che se il file si trova in:
file/manuale.pdf
allora il suo URL è:
URL url = getClass().getResource("/file/manuale.pdf")
Nota il "/" iniziale.
Se il file è in un jar allora l'url restituito punterà al documento contenuto nel JAR. Che non è un file. Non è un:
file://
Non essendo un file non puoi usarlo con Desktop. Desktop accetta solo File. La soluzione è banalissima: pigli l'URL e trasferisci il contenuto in un file temporeano che poi userai con Desktop.open. A meno che non sia un pdf da mille tonnellate l'utente neppure si accorgerà del trasferimento.
Sono nel pallone :doh:
Qua non ho capito proprio XD
http://img524.imageshack.us/img524/2065/invocafile.jpg
Nell'else che dovrei mettere?
http://img25.imageshack.us/img25/5149/iconxap.jpg
Non fare caso alle altre classi, sono per prova.
Sti maledetti, è questo il modo di fare le cose! :D sto scherzando :D
Tutto ok.
I due percorsi sono:
/File/c.pdf
e
/File/msn.png
E devi prenderli entrambi con getResource:
URL manuale = InvocaFile.class.getResource("/File/c.pdf");
e
URL urlIcona = NewJFrame.class.getResource("/File/msn.png");
L'URL dell'icona puoi usarlo direttamente con ImageIcon:
labelAvatarAmico.setIcon(new ImageIcon(urlIcona));
L'altro URL devi prima passarlo in un file. Ad esempio:
package File;
import java.awt.Desktop;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
public class InvocaFile {
public static void openManuale() throws IOException {
URL manuale = InvocaFile.class.getResource("/File/c.pdf");
File temp = File.createTempFile("manuale", ".pdf");
BufferedInputStream in = new BufferedInputStream(manuale.openStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(temp));
try {
for(int i = in.read(); i != -1; i = in.read()) {
out.write(i);
}
} finally {
try { in.close(); } finally { out.close(); }
}
Desktop.getDesktop().open(temp);
}
}
Grazie mille! Non so come ringraziarti.
Ho notato una cosa, su Windows 7 64bit non si apre il pdf. Come mai? Mi riporta errore di IOException bla bla... sia in .jar che con l'IDE.
l'eccezione completa com'è?
Non so perchè fallisce l'apertura.Su XP e Ubuntu va, forse dipende dalla jvm su W7 64bit? Ma tu sei programmatore?
20-ago-2009 16.20.37 Parametri.NewJFrame jMenuItemManualeIstruzioneActionPerformed
GRAVE: null
java.io.IOException: Failed to open file:/C:/Users/Nexus/AppData/Local/Temp/manuale1264765352396561706.pdf. Error message: Errore non specificato.
at sun.awt.windows.WDesktopPeer.ShellExecute(WDesktopPeer.java:59)
at sun.awt.windows.WDesktopPeer.open(WDesktopPeer.java:36)
at java.awt.Desktop.open(Desktop.java:254)
at File.InvocaFile.openManuale(InvocaFile.java:42)
at Parametri.NewJFrame.jMenuItemManualeIstruzioneActionPerformed(NewJFrame.java:718)
at Parametri.NewJFrame.access$1500(NewJFrame.java:17)
at Parametri.NewJFrame$16.actionPerformed(NewJFrame.java:680)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1225)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1266)
at java.awt.Component.processMouseEvent(Component.java:6263)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6028)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2475)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Non sono programmatore.
Fai un espertimento con JDIC
https://jdic.dev.java.net/
e prova ad aprire lo stesso file (JDIC è il progetto originale da cui è stata prelevata la classe Desktop che però è stata rimaneggiata).
Se funziona con JDIC è un problema di java.awt.Desktop. La soluzione è usare JDIC che è peraltro una libreria molto piccola.
Grazie di tutto, ti farò sapere :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.