我的申请基本上是photo browser。我的方法(不要评判我,我是java的新手)是让ArrayList
填充BufferedImages
,然后将图像添加到JList
(左侧)。
这是我获取图片的方式:
private void getFullImage() {
BufferedImage im = null;
ImageReader imageReader = null;
try {
System.out.println("Loading "+original+"...");
String suffix = Utils.getFileExt(original.getName(), "jpg");
@SuppressWarnings("rawtypes")
Iterator readers = ImageIO.getImageReadersBySuffix(suffix);
imageReader = (ImageReader)readers.next();
imageReader.setInput(new FileImageInputStream(original));
im = imageReader.read(0);
imageReader.dispose();
} catch (Exception e)
{
e.printStackTrace();
}
this.img = im;
}
然后,在我获取所有数据后,我会将图像添加到JList
:
Vector vector = new Vector();
JPanel container = null;
PhotoPanel pp = null;
Photo p = null;
for(int i=0;i<files.length;i++)
{
p = new Photo(files[i]);
pp = new PhotoPanel(p);
container = new JPanel(new BorderLayout());
container.add(pp,BorderLayout.CENTER);
container.setBorder(BorderFactory.createTitledBorder(p.getTitle()));
vector.addElement(container);
}
plist.setListData(vector);
如果我有10个文件,该应用程序运行良好。问题是我有更多的图像要显示。然后我会得到一个例外:Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
。所以,我知道我的方法非常糟糕,我想知道如何拍摄和存储所有图像并让它们显示在JList
中。也许使用缓存?我读过有关SoftReference
的内容,但我真的不知道如何使用它。感谢。
答案 0 :(得分:5)
问题主要有两个可能的原因:
第一个,我发布的更多信息是警告,而不是实际原因,是因为System.out.println()
在控制台上打印了过多的数据。
我不确定它是仅在NetBeans或所有开发工具中发生的。但不管怎样,它需要一个真正荒谬的打印量来触发它,我怀疑你有很多文件加载。
无论如何,如果您对System.out.println("Loading "+original+"...");
行的意图是针对永久/生产日志记录,而不是为了开发/调试而暂时放置代码,那么最好使用Logger
。 {1}}。您可以在this SO answer中阅读TL; DR版本的说明,您可以通过其中提供的链接进一步阅读,包括官方文档。
另一个原因,当然是您的原因,就是您同时加载了太多数据。解决方案是:
答案 1 :(得分:0)
我在使用大型图像时遇到了很多困难(尽管在SWT中),而OutOfMemory和NoMoreHandles(如果没有足够的内存,甚至可能会发生)都是一场噩梦。我认为没有办法保留大图像或在内存中有大量图像。我同意Andrew的评论,但只是想补充一点,根据你的要求,你可以尝试扩展画布(或Swing中的任何内容)并直接在其上绘制你的图像,而不将其保存在内存中(类似于PaperClips#打印预览)。当然,你需要进行一些计算来正确布局图像,但我认为,在这种情况下,你可以克服你的内存问题(但是还会遇到其他一些问题:))