Swings ImageIcon构造函数非常慢

sim*_*sjo 3 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)
Run Code Online (Sandbox Code Playgroud)

我的应用程序在启动时加载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;
}
Run Code Online (Sandbox Code Playgroud)

tra*_*god 6

要减轻观察到的延迟,请在a的后台线程中加载和重新采样图像SwingWorker.您可以publish()将它们变为可用,并将其添加到List<Image>您的实现中process().最初加载的图像可以被选择和操作,而其余图像正在加载.让进度指示器监听属性更改.这里这里可以看到相关的例子.

补遗总结评论:

  • 工作线程可以提升用户的感知活跃度.

  • 在开始时知道图像的数量可以允许进度指示器中更精细的粒度.

  • 专注于瓶颈,该scaleDownTo()方法似乎呼吁getScaledInstance(); 有关详细信息,请参阅"危险"Image.getScaledInstance(),并考虑此处此处检查的替代方案.