java—仅当jlist项可见时才加载某些内容

kyvafyod  于 2021-07-05  发布在  Java
关注(0)|答案(2)|浏览(261)

我正在实现一个包含很多元素的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,其中包含堆叠的项,我在其中检查每个元素的可见性?
谢谢

xpcnnkqh

xpcnnkqh1#

罪魁祸首似乎是 BasicListUI 在它的 updateLayoutState() . 在绘制操作过程中,它将遍历 dataModelupdateLayoutStateNeeded 标志被设置(在每次属性更改之后,以及在从 dataModel ). 在每个单元格上,它将调用 getListCellRendererComponent 方法并使您加载图标。如果你设置了 fixedCellHeight 以及 fixedCellWidth jlist示例上的字段。
您可以尝试使用两种公共方法设置固定的高度和宽度:
setFixedCellHeight(int) setFixedCellWidth(int) 顺便说一句:一般来说,从文件系统加载图标会很慢,如果在事件调度线程中执行,会导致gui感觉迟钝。这通常是一个更大的图像问题,加载文件可能需要时间。如果还没有,可以考虑将图标加载到单独的线程中。这可以通过在前面加载一个共享的“图标不可用图像”来实现,当您的 Page 如果页面特定的图标为空,则可以触发所需文件的加载,然后返回“icon unavailable image”,一旦 Page 已加载,将其分配给 Page 示例并触发重新绘制。只是一个想法。

piztneat

piztneat2#

我相信jlist会遍历所有项并调用呈现器来确定列表的首选大小。
您可以通过使用setprototypecellvalue(…)方法来防止这种情况。当然,对于滚动窗格中的所有可见项,仍将调用呈现器。

相关问题