1

since i am not a java swing expert i need some help to understand why my images in my JList do not appear.

I have a JList that pops up containing all products (with inline pictures) while the user enters a search criteria. The results come from lucene and will be rendered in a JList in real time.

To lazy load the inline product images i am using a swingworker inside my rendering class.

Any help would be great!

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);
    }
};
Ugur Teker
  • 169
  • 2
  • 14
  • 2
    You need a cache for loaded images. On rendering when the image is missing in the cache you should start the loading of image into cache. After loading image you must tell the model that the corresponded line of list is changed. If image is in cache you should directly show the image. – Sergiy Medvynskyy Sep 29 '14 at 14:28
  • Thanks for your response. What exactly do you mean with "tell the model that the corresponded line of list is changed"? I do set the image already with the JLabel.setIcon() method in the async thread – Ugur Teker Sep 29 '14 at 14:39
  • You can modify the label only during the rendering process (when the method getListCellRendererComponent is called). When you do it outside it will take no effect. So you need to save the icon in the cache and trigger repainting of the row. The best way to do it: call the method AbstractListModel.fireContentsChanged (this method is protected but you can override it and make it public). – Sergiy Medvynskyy Sep 29 '14 at 15:53
  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example). 2) One way to get images for an example, is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). – Andrew Thompson Sep 29 '14 at 22:03

0 Answers0