【问题标题】:Out of Memory while showing an image in a JPanel swing在 JPanel 摆动中显示图像时内存不足
【发布时间】:2012-03-20 11:10:00
【问题描述】:

我正在尝试在 JPanel 中显示图像。我正在为此使用 swingx 库 - ImagePainter。因此,我创建了一个 JXPanel,并将背景画家设置为 ImagePainter。

现在,我需要在 2 个单独的 JFrame 中的 2 个 JPanel 上显示相同的图像。当我这样做时,我遇到了堆空间问题。在这种情况下,我是否共享同一个 ImagePainter 实例?那会有帮助吗?但这意味着如果我需要显示多个独特的图像,无论如何我都会遇到内存不足的错误。我做错了什么吗?

我使用的代码如下:

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;
}

错误堆栈跟踪如下:

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)

更新:这是显示问题的 SSCCE: 您需要 jgoodies 表单布局 jar 和类路径中的 swingx jar 才能编译。再次单击 On Image 两次,对我来说,出现内存不足错误。我使用的图片也附上了。

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;
    }

}

【问题讨论】:

  • 图像的像素和位深度有多大? “2 个单独的 JFrame” 一个应用程序通常应该只有 one frame
  • imageLocation 的文件有多大?如果你指向一个较小的文件会发生什么?
  • 你确定你没有以某种方式循环调用 getImagePainter() 吗?
  • 像素 - 4032*3024。 Inspector 显示 314 像素/英寸。这是位深度吗?对不起 2 帧.. 我有一个帧和一个对话框。图片大小为 2.6 MB。
  • 谢谢 - 我可以重现 OOME(使用第 5 个打开的对话框),但它与 SwingX 无关(对于普通的 JLabel 也是如此)。也许对 imagePainter 所做的事情有误解:虽然它将图像缩放到所需的大小,但它保留了完整的图像,这可能只是占用了太多的内存。如果是这样,我看到的唯一方法是先将其缩小到拇指,然后插入画家

标签: java swing swingx


【解决方案1】:

你只是没有足够的内存。获得多少内存图像取决于它的分辨率。

所以图像可能很大,或者您一次有两个以上的图像。

接下来认为你可以做的是增加java进程的内存(xmx)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-27
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多