我编写了一个程序,其中应在动作事件中打开pdf文件(您可以在下面查看我的代码)。
menuElementHilfe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
File hilfe = new File ("src\\resources\\Hilfe.pdf");
try {
java.awt.Desktop.getDesktop().open(hilfe);
} catch (IOException e) {
e.printStackTrace();
}
}
});
如果我通过Eclipse执行程序,则一切正常,但是导出为可运行的jar后,出现以下异常:
线程“ AWT-EventQueue-0”中的异常java.lang.IllegalArgumentException:文件src \ resources \ Hilfe.pdf不存在。
感谢任何反馈
答案 0 :(得分:0)
您检索资源的方式可能是问题所在。试试这个:
menuElementHilfe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
File hilfe = new File(getClass().getResource("/resources/Hilfe.pdf").getFile());
try {
java.awt.Desktop.getDesktop().open(hilfe);
} catch (IOException e) {
e.printStackTrace();
}
}
});
在Eclipse中运行时,您将目标定位为构建路径中的文件。 从JAR / WAR运行时,URL不同,看起来像“ jar:file:/your-path/your-jar.jar!/Hilfe.pdf” ,这不是您在调用时设置的new File(...)因此,要获取内部资源的正确URL,必须根据需要使用诸如getResource或getResourceAsStream之类的方法。
查看以下说明以获取更多信息:) https://docs.oracle.com/javase/8/docs/technotes/guides/lang/resources.html
[编辑]
我假设您正在使用某些Swing应用程序,但是我不知道您是否知道在AWT-EventQueue线程中执行类似的任务会冻结UI。 为了防止这种情况,您必须在另一个线程中运行与UI无关的内容。
这是使用SwingUtilities.invokeLater(Java 5和更低版本)方法和/或SwingWorker类(自Java 6开始)实现的。
如本answer
所述您应该将先前的解决方案放入类似的内容中:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Your UI unrelated code here
}
});
答案 1 :(得分:0)
资源可以打包在应用程序jar中,因此可以打包为File(物理磁盘文件) 不可能。将其复制到一个临时文件中,以便桌面可以打开它。
menuElementHilfe.addActionListener(evt -> {
Path tmp = Files.createTempFile("hilfe-", ".pdf");
Files.copy(getClass().getResourceAsStream("/Hilfe.pdf"), tmp);
try {
Desktop.getDesktop().open(tmp.toFile());
tmp.toFile().deleteOnExit();
} catch (IOException e) {
e.printStackTrace();
}
});
另一个区别是正斜杠,并且路径与Windows File相对,区分大小写。
出现问题后
menuElementHilfe.addActionListener(evt ->
SwingUtilities.invokeLater(() -> {
Path tmp = Files.createTempFile("hilfe-", ".pdf");
Logger.getLogger(getClass().getName()).log(Level.INFO, "actionPerformed "
+ tmp + "; event: " + evt);
Files.copy(getClass().getResourceAsStream("/resources/Hilfe.pdf"), tmp);
try {
Desktop.getDesktop().open(tmp.toFile());
//tmp.toFile().deleteOnExit();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.WARN, "Error with " + tmp,
e);
}
}));
Desktop
访问的寿命比Java应用程序长。invokeLater
是为了使actionPerformed上没有冻结的GUI。