我正在实现一个包含很多元素的jlist。每个元素对应一个图像,所以我想在列表的每一行中显示它们的大小调整预览。我已经实现了一个自定义的imagecellrenderer,它扩展了jlabel,并且在getListCellRenderComponent上创建了缩略图(如果没有该元素的缩略图的话)。每一行对应于一个页面类,我在其中存储图像的路径和应用于jlabel的图标。每个页面对象都放在defaultlistmodel中以填充jlist。渲染代码如下所示:
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
Page page = (Page) value;
if (page.getImgIcon() == null)
{
System.out.println(String.format("Creating thumbnail of %s", page.getImgFilename()));
ImageIcon icon = new ImageIcon(page.getImgFilename());
int thumb_width = icon.getIconWidth() > icon.getIconHeight() ? 128 : ((icon.getIconWidth() * 128) / icon.getIconHeight());
int thumb_height = icon.getIconHeight() > icon.getIconWidth() ? 128 : ((icon.getIconHeight() * 128) / icon.getIconWidth());
icon.setImage(getScaledImage(icon.getImage(), thumb_width, thumb_height));
page.setImgIcon(icon);
}
setIcon(page.getImgIcon());
}
我认为在调用单元格呈现器的列表中只有一个特定的项是可见的,但是我看到所有的thumnail都是在我将page对象添加到列表模型时创建的。我试过在jlist中设置模型之后加载项目,或者在开始附加项目之后首先设置模型,但是结果是一样的。是否有任何方法仅在必要时加载数据,或者我是否需要创建一个自定义控件,比如jscrollpanel,其中包含堆叠的项,我在其中检查每个元素的可见性?
谢谢
2条答案
按热度按时间xpcnnkqh1#
罪魁祸首似乎是
BasicListUI
在它的updateLayoutState()
. 在绘制操作过程中,它将遍历dataModel
当updateLayoutStateNeeded
标志被设置(在每次属性更改之后,以及在从dataModel
). 在每个单元格上,它将调用getListCellRendererComponent
方法并使您加载图标。如果你设置了fixedCellHeight
以及fixedCellWidth
jlist示例上的字段。您可以尝试使用两种公共方法设置固定的高度和宽度:
setFixedCellHeight(int)
setFixedCellWidth(int)
顺便说一句:一般来说,从文件系统加载图标会很慢,如果在事件调度线程中执行,会导致gui感觉迟钝。这通常是一个更大的图像问题,加载文件可能需要时间。如果还没有,可以考虑将图标加载到单独的线程中。这可以通过在前面加载一个共享的“图标不可用图像”来实现,当您的Page
如果页面特定的图标为空,则可以触发所需文件的加载,然后返回“icon unavailable image”,一旦Page
已加载,将其分配给Page
示例并触发重新绘制。只是一个想法。piztneat2#
我相信jlist会遍历所有项并调用呈现器来确定列表的首选大小。
您可以通过使用setprototypecellvalue(…)方法来防止这种情况。当然,对于滚动窗格中的所有可见项,仍将调用呈现器。