Swing JList延迟加载映像
由于我不是java swing专家,我需要一些帮助来理解为什么我的JList中的图像没有出现 我有一个JList,当用户输入搜索条件时,它会弹出一个包含所有带有内联图片的产品的列表。结果来自lucene,将在JList中实时呈现 要延迟加载内联产品图像,我在渲染类中使用swingworker 任何帮助都会很好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
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获取图像的一种方法例如,热链接到中看到的图像。您好,谢谢您的帮助。这解决了我的问题。