我目前正在构建一个资源非常庞大的应用程序,其中包含大量图像和一些用户可以显示和交互的PDF文件。现在我正在使用
加载图像MainMenu.class.getResource("ImageName.png");
然后设置为JPanel或类似的显示。但是,加载这些图像有时需要很长时间,并且在尝试加载应用程序时会使应用程序停止运行。甚至在我的工作笔记本电脑上也会发生这种情况,这是一个不错的规范,从来没有让用户的PC更老。
有没有人有更简化的方法呢?
答案 0 :(得分:2)
由于您提到您的整个应用程序停止运行,因此您应确保未在事件处理线程中完成加载工作。您应该在SwingWorker
:
public class ImageLoadingWorker extends SwingWorker<URL, Object> {
private String resourceName;
public ImageLoadingWorker(String resourceName) {
this.resourceName = resourceName;
}
@Override
protected URL doInBackground() throws Exception {
return getClass().getClassLoader().getResource(resourceName);
}
@Override
protected void done() {
// use result here
URL result = get();
// ...
}
}
然后:
new ImageLoadingWorker("dummy/dummy/ImageName.png").execute();
查看此oracle文档以获取更多详细信息:Improve Application Performance With SwingWorker in Java SE 6
答案 1 :(得分:1)
我建议使用像JProfiler这样的工具或免费工具来分析读取操作。
您可能遇到I / O缓慢的问题。一旦检索到url,就必须打开一个输入流,确保使用BufferedInputStream。
此外,您可以尝试将资源提取到临时目录并读取它们,这样可以节省jar解压缩的开销。
此外,您可以考虑缩小图像大小,使用像微小的png这样的工具,并尝试减小png文件的大小。它们越小它们导入的速度越快。
您可以使用像JAI(Java Advanced Image API)这样的图像库,因为您没有呈现渲染代码,很难说出问题出在哪里。
考虑使用摇摆工作者,正如之前的帖子所暗示的那样。
的问候,
答案 2 :(得分:0)
在处理动作事件时不加载图像(或其他繁重处理):
@Override
public void actionPerformed(ActionEvent event) {
... ImageIO.readImage(...);
}
这会立即冻结系统。相反,一些推迟已经使系统保持响应:
@Override
public void actionPerformed(ActionEvent event) {
SwingUtilities.invokeLater(() -> {
... ImageIO.readImage(...);
});
}
当asynchrone可行时,在后台做事(提到摇摆工作者)可能是另一个步骤。
内存泄漏,竞争条件,质量保证。
深入研究瓶颈,内存和CPU使用情况。
最后的手段是减少资源。这可以部分地利用系统本身:Desktop.getDesktop().open(pdf);
而不是您自己的PDF查看器。
将多个图像合并为一个。在PropertyResourceBundle和ListResourceBundle之间进行选择。没有琐碎的图像(带有不同文本的按钮)。
可能上面你已经做了一些。愿它可以帮助别人。