Swings ImageIcon构造函数非常慢

时间:2014-01-02 21:24:11

标签: java performance swing

编辑:有关此问题的答案,请参阅此答案的评论。 TLDR:瓶颈是缩放图像,但分析显示这是ImageIcon构造函数中的一个问题。


$ java -version
Picked up _JAVA_OPTIONS: -Dswing.aatext=true -Dawt.useSystemAAFontSettings=on
java version "1.7.0_45"
OpenJDK Runtime Environment (IcedTea 2.4.3) (ArchLinux build 7.u45_2.4.3-1-x86_64)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

我的应用程序在启动时加载了1,380个图标。加载代码如下所示。使用SSD磁盘,ImageIcon构造函数调用实际上比磁盘读取更昂贵(尽管磁盘读取可能会使用某些缓存...)

加载图标需要5.4s,在ImageIcon构造函数中花费3.2s。

有没有办法加速ImageIcon构建或使用别的东西?

private ImageIcon setIcon(LogicalIcon iconInfo, int size) {
    ImageIcon icon = iconImages.get(iconInfo.getIconName());
    if(icon == null) {
        BufferedImage image = null;
        try {
            image = ImageIO.read(getBestPreviewIcon(iconInfo).getFile());
            icon = new ImageIcon(ImageUtils.scaleDownTo(image, new Dimension(size, size)));
            iconImages.put(iconInfo.getIconName(), icon);
        } catch (IOException e) {
            // FIXME: Add a "Missing Image" icon
            e.printStackTrace();
        }
    }
    setIcon(icon);
    return icon;
}

1 个答案:

答案 0 :(得分:6)

要减轻观察到的延迟,请在SwingWorker的后台线程中加载和重新采样图像。您可以publish()分别使用List<Image>,并将其添加到process()实施中的scaleDownTo()。最初加载的图像可以被选择和操作,而其余图像正在加载。让进度指示器监听属性更改。相关示例见herehere

补遗总结评论:

  • 工作线程可以增强用户对活力的看法。

  • 一开始就知道图像的数量,可以在进度指示器中实现更精细的粒度。

  • 关注瓶颈,getScaledInstance()方法似乎呼叫{{1}};有关详情,请参阅The Perils of Image.getScaledInstance(),并考虑已审核的替代方案herehere