JList是否有懒加载实现?

4
有没有一种方法可以在Swing的JList中实现延迟加载?
4个回答

11

在某种程度上,是的。您可以创建一个自定义的ListModel,该模型使用getElementAt(int index)方法来加载正确的值,如果它还没有被加载。请参阅JList的Javadocs中的示例:

// This list model has about 2^16 elements.  Enjoy scrolling.

ListModel bigData = new AbstractListModel() {
    public int getSize() { return Short.MAX_VALUE; }
    public Object getElementAt(int index) { return "Index " + index; }
};

谢谢你的回答,我尝试了一下,发现我的界面之所以很慢,是因为有人编写并使用了一个自定义的“排序”列表模型。 - user105413

5
我解决了。我错过了在JList API文档顶部讨论的解决方案。
在我在另一个答案中发布的示例源代码中,在创建JList后添加这行代码(和注释):
  // Tell JList to test rendered size using this one value rather
  // than every item in ListModel. (Much faster initialization)
  myList.setPrototypeCellValue("Index " + Short.MAX_VALUE); 

问题在于JList默认情况下会访问整个ListModel中的每个项目,以确定运行时所需的显示大小。上面添加的代码行覆盖了该默认设置,并告诉JList仅检查传递的一个值。这个值充当模板(原型),用于调整JList的显示大小。
请参见:

http://java.sun.com/javase/6/docs/api/javax/swing/JList.html#prototype_example


谢谢这个 - 这也是我错过的东西。 - D.T. Atkinson

2

补充一下其他答案的内容,当您创建自己的ListModel实现时,加载数据时需要调用:

fireIntervalAdded(Object source,int index0, int index1)

假设您正在逐步加载数据到列表中。这将导致使用它作为模型的JList进行更新。
请参阅fireIntervalAdded文档

哦,我想知道为什么这个示例没有做到这一点。也许更多是为了美观(保持滚动条同步)。 - Michael Myers
谢谢你的帮助,我在自定义列表模型中实现“addAll”方法时使用了它。 - user105413

1

不正确。上面的JList并没有进行懒加载。

Swing坚持访问整个ListModel中的每个项目,同时在屏幕上显示它。此外,在访问所有项目之后,Swing会重新访问屏幕上可见的前n个项目(在视口中,而不是在下方的屏幕外)。

运行这个简单的“TestJList”类来证明它。每次执行'getElementAt'时,我都调用println。您可以清楚地看到Swing为ListModel中的每个项目调用该方法。

这在我的MacBook unibody上发生,运行Mac OS X 10.6.2和Java:

"1.6.0_17" Java(TM) SE Runtime Environment (build 1.6.0_17-b04-248-10M3025) Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)

import javax.swing.*;

/**
 *  This example proves that a JList is NOT lazily-loaded.
 */
public class TestJList {
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("HelloWorldSwing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create an artificial ListModel. 
        ListModel bigData =
            new AbstractListModel() {
                public int getSize() {
                    // return Short.MAX_VALUE;  // Try this if you have a long while to waste.
                    return 10;
                }

                public Object getElementAt(int index) {
                    System.out.println("Executing 'getElementAt' # " + index);
                    return "Index " + index;
                }
            };

        // Create a JList.
        JList myList = new JList(bigData);

        // Add the JList to the frame.
        frame.getContentPane().add(myList);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(
            new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
    }
}

运行该代码,您将看到:
Executing 'getElementAt' # 0
Executing 'getElementAt' # 1
Executing 'getElementAt' # 2
Executing 'getElementAt' # 3
Executing 'getElementAt' # 4
Executing 'getElementAt' # 5
Executing 'getElementAt' # 6
Executing 'getElementAt' # 7
Executing 'getElementAt' # 8
Executing 'getElementAt' # 9
Executing 'getElementAt' # 0
Executing 'getElementAt' # 1
Executing 'getElementAt' # 2
Executing 'getElementAt' # 3
Executing 'getElementAt' # 4
Executing 'getElementAt' # 5
Executing 'getElementAt' # 6
Executing 'getElementAt' # 7
Executing 'getElementAt' # 8
Executing 'getElementAt' # 9

-完-


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接