我使用了一个自定义的listcellrenderer,它有一个列表,并设置了标题和图像,但它真的很滞后,因为每次滚动时图像都会不断加载。有什么办法我能解决这个问题吗?这是我的代码:
@Override
public Component getListCellRendererComponent(JList<? extends Movie> list, Movie value, int index, boolean isSelected, boolean cellHasFocus) {
this.titleHolder.setText(value.getTitle());
this.imageHolder.setIcon(new ImageIcon(value.getPoster()));
return this;
}
我基本上希望每次滚动列表时都停止加载图像,因为这会导致应用程序严重滞后。提前谢谢。
解决方案是创建一些排序缓存,正如weisj在评论部分中提到的那样。
如果您还没有实现Movie
类的hashCode()
和equals()
方法,请实现它们。
现在创建您的缓存:
private Map<Movie,ImageIcon> moviePostersCache = new HashMap<>();
然后,在getListCellRendererComponent
:内部
@Override
public Component getListCellRendererComponent(JList<? extends Movie> list, Movie value, int index,
boolean isSelected, boolean cellHasFocus) {
this.titleHolder.setText(value.getTitle());
if (!moviePostersCache.containsKey(value))
moviePostersCache.put(value, new ImageIcon(value.getPoster()));
this.imageHolder.setIcon(moviePostersCache.get(value));
return this;
}
海报将被人们铭记。在第一次渲染之后;重新加载"-Movie#getPoster
将不会被调用。
现在,如果gui中有很多电影,可以考虑使用弱哈希图。
您可以基于Movie#getTitle
缓存图标(我认为其类型为String
.
private Map<String, Icon> iconCache = new HashMap<>();
@Override
public Component getListCellRendererComponent(JList<? extends Movie> list, Movie value, int index, boolean isSelected, boolean cellHasFocus) {
this.titleHolder.setText(value.getTitle());
this.imageHolder.setIcon(iconCache.computeIfAbsent(value.getPoster(), ImageIcon::new));
return this;
}