My application is basically a photo browser . My approach (don't judge me, I am new to java) was to have an ArrayList
filled with BufferedImages
and then add the images to the JList
(to the left).
This is how I get an image :
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;
}
and then, after I fetched all the data, I would add the images to my 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);
If I have for example 10 files, the app works pretty well. The problem is when I have a lot more images to show. Then I would get an exception : Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
. So, I know my approach is a very poor one, and I am wondering how should I take and store all the images and have them to be displayed in the JList
. Maybe using the cache memory? I read something about SoftReference
but I don't really know how to use it. Thanks.
There are two main possible causes for the problem:
The first, and which I'm posting more as a warning than as an actual cause in your case, is that an excessive amount of data is being printed on the console with the System.out.println()
.
I am unsure if it only occurs with NetBeans or all Development tools. But either way, it requires a truly absurd amount of printing for it to be triggered, and i doubt you have that many files loading.
Anyways, if your intent with the System.out.println("Loading "+original+"...");
line is for a permanent/production logging, rather than something you've put on code just temporarily for development/debug purposes, then you are better off with a proper Logger
. You can read a TL;DR version of instructions in this SO answer , and you can read further, including the official documentation, through the links provided there.
The other cause, which is quite certainly your's, is that you are having too much data loaded at the same time. The solutions are to either:
I was struggling a lot with large images (in SWT though) and those OutOfMemory and NoMoreHandles (which might happen even, if there is not enough memory) were a nightmare. I think there is no way, to keep large images or have a lot of images in memory. I agree with Andrew's comment, but just wanted to add, that depending on your requirements you could try to extend a canvas (or whatever there is in Swing) and DRAW your images directly on it, without holding those in memory (similar for PaperClips#PrintPreview). Sure, you will need to have some calculations to layout images correctly, but I think, that in this case you might overcome your problems with memory (but get some other problems:))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.