0

I am trying to display an image in a JPanel. I am using the swingx library - ImagePainter for this. So I create a JXPanel with the background painter set to the ImagePainter.

Now, I need to show the same image on 2 JPanels which are in 2 separate JFrames. When I do that I get a heapspace issue. In this case, do I share the same instance of the ImagePainter? Would that help? But that would mean that if I need to show more than one unique image I would get a out of memory error anyway.. Anything I am doing wrong?

The code I use is as below:

public static ImagePainter getImagePainter(String imageLocation) {
    ImagePainter imgPainter=null;
    try {
        imgPainter = new ImagePainter(ImageIO.read(new File(imageLocation)));
    } catch (IOException e) {
        throw new SwingObjectRunException(e, ErrorSeverity.SEVERE, CommonUI.class);
    }
    return imgPainter;
}

The error stack trace is as below:

Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:59)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397)
    at java.awt.image.Raster.createWritableRaster(Raster.java:938)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2879)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:980)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:948)
    at javax.imageio.ImageIO.read(ImageIO.java:1422)
    at javax.imageio.ImageIO.read(ImageIO.java:1282)

Update: Here's the SSCCE that shows the problem: You need jgoodies form layout jar and the swingx jar in your classpath for this to compile. Click On Image again twice and for me I get an out of memory error. The Image I used is attached as well.

Image to use

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.painter.ImagePainter;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;


public class Photo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try{
            JFrame frame=new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel panel=new JPanel();
            panel.setLayout(new FormLayout("5dlu,fill:250px,15dlu", "5dlu,fill:150px,15dlu,fill:pref,5dlu"));

            panel.add(getImagePanel(), new CellConstraints(2, 2));

            JButton btnOpenDiag=new JButton("Open Image Again");
            panel.add(btnOpenDiag,new CellConstraints(2, 4, 1, 1, CellConstraints.CENTER, CellConstraints.FILL));

            btnOpenDiag.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        JDialog dialog=new JDialog();
                        JPanel panel=new JPanel();
                        panel.setLayout(new FormLayout("5dlu,fill:250px,15dlu", "5dlu,fill:150px,5dlu"));
                        panel.add(Photo.getImagePanel(), new CellConstraints(2, 2));
                        dialog.setContentPane(panel);
                        dialog.pack();
                        dialog.setVisible(true);
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            });

            frame.setContentPane(panel);
            frame.pack();
            frame.setVisible(true);
        }catch(Exception e){

        }


    }

    protected static JXPanel getImagePanel() throws IOException {
        JXPanel imgPanel=new JXPanel();
        ImagePainter painter=new ImagePainter(ImageIO.read(new File(Photo.class.getResource("image.jpg").getFile())));
        painter.setFillHorizontal(true);
        painter.setFillVertical(true);
        imgPanel.setBackgroundPainter(painter);
        return imgPanel;
    }

}
sethu
  • 8,181
  • 7
  • 39
  • 65
  • How big are the images in pixels and bit-depth? *"2 separate JFrames"* A application should generally have only [one frame](http://stackoverflow.com/a/9554657/418556). – Andrew Thompson Mar 20 '12 at 11:17
  • How large is the file at imageLocation? What happens if you point to a smaller file? – Tony Ennis Mar 20 '12 at 11:25
  • Are you sure you're not somehow calling getImagePainter() in a loop? – Tony Ennis Mar 20 '12 at 11:29
  • Pixels - 4032*3024. Inspector shows 314 pixels/inch.. is that the bit depth? Sorry about the 2 frames.. I have one frame and one dialog. The image is 2.6 MB. – sethu Mar 20 '12 at 11:41
  • can you update it somewhere? would give it a try (as mostly when SwingX is involved, there _is_ a non-zero probability you hit a bug :-) – kleopatra Mar 20 '12 at 12:01
  • @kleopatra - I'll try to extract a common SSCCE and update it here. I'll attach the image or put into a dropbox. Will do this tonight. – sethu Mar 20 '12 at 13:20
  • Posted an SSCCE that shows the problem. CLick on the button twice. Not sure if this will be the limitation of heap size regardless. – sethu Mar 21 '12 at 04:05
  • 1
    thanks - I can reproduce the OOME (with the 5th open dialog) but it's unrelated to SwingX (same for plain JLabel). Maybe a misconception as to what an imagePainter does: while it scales the image to the required size, it keeps the complete image around which probably simply takes too much memory. If so, the only way I see is to first scale it down to a thumb and then plug into the painter – kleopatra Mar 21 '12 at 08:51
  • Thanks.. I'll fix this by just closing the previous dialog first and then opening the next one. Will tell the guys side by side comparison is difficult. It was a nice to have anyway :) – sethu Mar 21 '12 at 09:43

1 Answers1

0

You just don't have enough memory. How much memory image get depends on it's resolution.

So images are probably huge, or you have more then two images at once.

Next think you can do is increase memory (xmx) of java process.

bugs_
  • 3,544
  • 4
  • 34
  • 39