将图像加载到JComboBox

时间:2017-10-14 14:06:30

标签: java image swing jcombobox imageicon

我正在向JComboBox加载50个图像,我使用扩展DefaultListCellRenderer的自定义渲染器进行渲染。一切都有效,除了性能,因为我的应用程序使用400多MB的RAM。

这是我的渲染器:

public class ImageRenderer extends DefaultListCellRenderer{

private static final long serialVersionUID = 1L;

@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
        boolean cellHasFocus) {



    if(value!=null) {
        setText(((File)value).getName());
        setIcon(getScaledImageIcon(this, ((File)value)));
    }

    if(isSelected) {
        setBackground(Color.DARK_GRAY);
        setForeground(Color.WHITE);
    }
    else {
        setBackground(Color.WHITE);
        setForeground(Color.BLACK);
    }

    return this;
}

public ImageIcon getScaledImageIcon(JLabel label, File file) {
    ImageIcon image = new ImageIcon(file.getAbsolutePath());
    Image img = image.getImage();
    Image newImage = img.getScaledInstance(30, 30, Image.SCALE_SMOOTH);
    return new ImageIcon(newImage);
}

}

以下是将文件添加到JComboBox的代码:

public void loadOffers() {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            File[] offers = new File(workingDir.getAbsolutePath() + "/offers").listFiles();
            addedOffers.removeAllElements();
            for(int i=0;i<offers.length;i++)
                addedOffers.addElement(offers[i]);
            offersBox.setRenderer(new ImageRenderer());
        }
    });
}

以下是它的外观: enter image description here 幸运的是我的PC有16GB的内存,但这不是重点。请帮忙。

2 个答案:

答案 0 :(得分:0)

setIcon(getScaledImageIcon(this, ((File)value)));

问题是,每次显示组合框的弹出窗口时,您都在缩放图像。缩放后的图像应作为对象的一部分存储在模型中。

因此,您创建一个包含两个属性的自定义对象:

  1. 缩放图标
  2. 文本
  3. 然后您的自定义渲染器只显示两个值。

    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
            boolean cellHasFocus) {
    
    
        if(value!=null) {
            CustomObject o = (CustomObject)value;
            setText(o.getName());
            setIcon(o.getScaledIcon());
        }
    
        ...
    

答案 1 :(得分:0)

  

但这50张图片的原始尺寸总共为18MB,我的应用程序使用400MB来显示它们

压缩PNG文件。如果它们在磁盘上占用18 MB,那只意味着有许多相同的颜色可以很好地压缩。

为了显示它们,需要对它们进行解压缩,以使每个像素都具有RGB值(红色,绿色,蓝色)。因此,图像将在内存中使用width*height*3个字节。

如果您需要30x30像素的50张图像,您应该提前调整它们的大小,它们需要的内存大小超过50 * 30 * 30 * 3 = 135 kB。而800x600的50张图像需要至少50 * 800 * 600 * 3 = 72 MB。