Swing JList延迟加载映像

Swing JList延迟加载映像,swing,lazy-loading,jlist,Swing,Lazy Loading,Jlist,由于我不是java swing专家,我需要一些帮助来理解为什么我的JList中的图像没有出现 我有一个JList,当用户输入搜索条件时,它会弹出一个包含所有带有内联图片的产品的列表。结果来自lucene,将在JList中实时呈现 要延迟加载内联产品图像,我在渲染类中使用swingworker 任何帮助都会很好 public abstract class MatchRenderer implements ListCellRenderer { @Override public Componen

由于我不是java swing专家,我需要一些帮助来理解为什么我的JList中的图像没有出现

我有一个JList,当用户输入搜索条件时,它会弹出一个包含所有带有内联图片的产品的列表。结果来自lucene,将在JList中实时呈现

要延迟加载内联产品图像,我在渲染类中使用swingworker

任何帮助都会很好

public abstract class MatchRenderer implements ListCellRenderer {
   @Override
public Component getListCellRendererComponent(JList list, final Object value, int index,
        boolean isSelected, boolean cellHasFocus) {
    Component component = defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

    if (quickRenderMode) {
        return component;
    } else {
        try {
            component = renderHook(value, component);
        } catch (Exception e) {
            System.err.println("Search string: " + searchString);
            System.err.println(value.toString());
            e.printStackTrace();
        }

        JPanel itemPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel label = new JLabel(defaultIcon, SwingConstants.HORIZONTAL);
        itemPanel.add(label);
        itemPanel.add(component);

        if (value instanceof QoogleEntity && ((QoogleEntity) value).isProduct()) {
            QoogleEntity qoogleItem = (QoogleEntity) value;
            String imageUrl = qoogleItem.getQInfos().get(0).getqValue();

            //LAZY LOAD STARTS HERE...
            new ImageRetriever(label, imageUrl).execute();
        }
        return itemPanel;
    }
}

protected abstract Component renderHook(Object value, Component component);

class ImageRetriever extends SwingWorker<ImageIcon, String> {
    private JLabel lbImage;
    private String imageUrl;

    public ImageRetriever(JLabel lbImage, String imageUrl) {
        this.lbImage = lbImage;
        this.imageUrl = imageUrl;
    }

    @Override
    protected void done() {
        try {
            lbImage.setIcon(get());
            lbImage.repaint();
        } catch (Exception e) {
        }
    }

    @Override
    protected ImageIcon doInBackground() throws Exception {
        return ImageLoader.loadImageFromUrl(imageUrl, 80, 80);
    }
};

您需要为加载的图像提供缓存。在渲染时,当图像在缓存中丢失时,应开始将图像加载到缓存中。加载图像后,您必须告诉模型列表的对应行已更改。如果图像在缓存中,您应该直接显示图像。感谢您的回复。你说的“告诉模型列表的对应行已更改”到底是什么意思?我确实已经在异步线程中使用JLabel.setIcon方法设置了图像。只有在调用方法GetListCellRenderComponent时,才能在渲染过程中修改标签。当你在外面做的时候,它不会起作用。因此,您需要将图标保存在缓存中并触发行的重新绘制。最好的方法是:调用AbstractListModel.fireContentsChanged方法此方法受保护,但您可以覆盖它并将其公开。1要更快获得更好的帮助,请发布一个最小的完整可验证示例。2获取图像的一种方法例如,热链接到中看到的图像。您好,谢谢您的帮助。这解决了我的问题。