gpt4 book ai didi

java - ListCellRenderer 中的 ImageIcon 缓慢

转载 作者:行者123 更新时间:2023-12-04 06:14:52 29 4
gpt4 key购买 nike

我有一个 class GridPanel extends JPanel , 带有静态内部类 ToolSelectComboBox extends JComboBox ,它又具有两个静态内部类 ToolSelectComboBoxModel implements ComboBoxModelToolSelectComboBoxRenderer implements ListCellRenderer .面板显示 ToolSelectComboBox (TSCB),其构造函数将其模型和渲染器设置为我创建的自定义模型。盒子创建正确,其模型和渲染器工作正常。

但是,渲染器的 getListCellRendererComponent(...)方法使用 ImageIconJLabel它返回。该图标已正确加载,但是,当我第一次单击组合框(每次运行时)时,图像的加载时间恰好(或至少非常接近)一秒多一点。我会假设这是加载文件的一些滞后,除了

  • 这是我本地文件系统上的一个 4kB 文件
  • 当我添加 System.out.println result.setIcon(...) 之前和之后的命令命令,他们几乎立即跟随对方。

  • 我注意到的奇怪的事情是 println命令被触发两次,一次是在我单击框时,一次是在加载图标时。

    还可能值得注意的是,由于它旨在与覆盖父抽象类的单个方法的多个类一起使用(以生成图标的路径),当我注意到它工作缓慢时,我将代码从只需使用 getIcon 检索图标将各种大小的图标(16、32 和 64 像素平方)存储在 TreeMap<Tool.ImageSize, ImageIcon> 中的命令(其中 Tool 是我创建的具有 ImageIcon getIcon() 方法的接口(interface)。

    我所有的进口都井井有条。

    任何帮助,将不胜感激!

    如果我发布了太多代码,我深表歉意,但我想确保它是可以理解的。另一方面,如果您需要更多代码才能理解,请不要犹豫。

    代码(所有以“ * ”开头并具有类似注释文本的行都是折叠的 JavaDoc 标记,而不仅仅是困惑的代码):
    public class GridPanel extends JPanel {

    public static class ToolSelectComboBox extends JComboBox {

    // Combo box model `ToolSelectComboBoxModel` snipped

    * A renderer for the {@link ToolSelectComboBoxModel}. This may
    public static class ToolSelectComboBoxRenderer implements
    ListCellRenderer {

    * The default renderer. Only the icon and text are modified.
    protected DefaultListCellRenderer d = new DefaultListCellRenderer();

    @Override
    public Component getListCellRendererComponent(final JList list,
    final Object value, final int index,
    final boolean isSelected, final boolean cellHasFocus) {
    if (!ToolSelectComboBoxModel.class.isInstance(list.getModel())) {
    throw new IllegalStateException(
    "Cannot use a ToolSelectComboBoxRenderer on any list model type other than ToolSelectComboBoxModel.");
    }
    final JLabel result = (JLabel) d.getListCellRendererComponent(
    list, value, index, isSelected, cellHasFocus);
    result.setText(null);
    if (value != null) {
    result.setIcon(((Tool) value)
    .getIcon(Tool.IconSize.SIZE_32PX));
    }
    return result;
    }
    }

    public ToolSelectComboBox() {
    setModel(new ToolSelectComboBoxModel());
    ((ToolSelectComboBoxModel) getModel()).add(new CircleTool()); // shown below
    setRenderer(new ToolSelectComboBoxRenderer());
    }
    }

    * Create the panel.
    public GridPanel() {
    setLayout(new BorderLayout(0, 0));

    final ToolSelectComboBox toolSelectComboBox = new ToolSelectComboBox();
    add(toolSelectComboBox, BorderLayout.NORTH);

    final SquareGrid squareGrid = new SquareGrid(); // another class; this works fine
    add(squareGrid, BorderLayout.CENTER); // irrelevant to problem

    }

    }
    CircleTool类只有一个方法(覆盖 AbstractTool 的抽象方法来获取图像路径),并且由于该方法有效(它可以很好地获取路径,它只是加载缓慢的图标),我没有包含这个类。
    AbstractTool类(class):
    public abstract class AbstractTool implements Tool {

    /**
    * A {@link TreeMap} to map the icon sizes to their icons.
    */
    protected final TreeMap<Tool.IconSize, ImageIcon> map = new TreeMap<Tool.IconSize, ImageIcon>();

    /**
    * Constructs the tool and sets up the {@linkplain #map}.
    */
    public AbstractTool() {
    for (final Tool.IconSize size : Tool.IconSize.values()) {
    System.out.println("Putting value for " + size);
    map.put(size,
    new ImageIcon(Tool.class.getResource(getImagePath(size))));
    }
    }

    @Override
    public ImageIcon getIcon(final IconSize size) {
    return map.get(size);
    }

    /**
    * Gets the image path for the given image size.
    *
    * @param size
    * the size
    * @return the image path
    */
    protected abstract String getImagePath(Tool.IconSize size);

    }

    最佳答案

    but, the first time I click the combo box (on each run), the image takes a little more than a second to load. I would assume that this is some lag in loading the file



    这也是我的猜测。

    except that when I add System.out.println commands before and after the result.setIcon(...) command, they follow each other almost instantly



    当您单击组合框时,所有代码都会在 EDT 上运行,这意味着每个图标将按顺序加载。

    但是 System.out.println() 在单独的线程上运行,因此会立即显示。

    解决方案是在程序启动时加载图标。也就是说,每当您在 map 中定义/添加图标时,您都应该在那时阅读它们。您可能希望在单独的线程上执行此操作,以免阻止 GUI 显示。

    编辑:

    这是一个简单的 SSCCE,它在组合框中显示图标:
    import java.awt.*;
    import javax.swing.*;

    public class ComboBoxIcon extends JFrame
    {
    JComboBox comboBox;

    public ComboBoxIcon()
    {
    Object[] items =
    {
    new ImageIcon("about16.gif"),
    new ImageIcon("add16.gif"),
    new ImageIcon("copy16.gif")
    };
    comboBox = new JComboBox( items );
    getContentPane().add( comboBox, BorderLayout.NORTH );
    }

    public static void main(String[] args)
    {
    JFrame frame = new ComboBoxIcon();
    frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
    frame.pack();
    frame.setLocationRelativeTo( null );
    frame.setVisible( true );
    }
    }

    如果您需要更多帮助,则需要发布您的 SSCCE这说明了问题。

    关于java - ListCellRenderer 中的 ImageIcon 缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7379914/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com