我正在向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());
}
});
}
答案 0 :(得分:0)
setIcon(getScaledImageIcon(this, ((File)value)));
问题是,每次显示组合框的弹出窗口时,您都在缩放图像。缩放后的图像应作为对象的一部分存储在模型中。
因此,您创建一个包含两个属性的自定义对象:
然后您的自定义渲染器只显示两个值。
@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。