4

有没有办法用 Swing 的 JList 实现延迟加载?

4

4 回答 4

11

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

// 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; }
};
于 2009-05-12T14:53:45.117 回答
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

于 2010-03-28T09:55:03.680 回答
2

只是添加到另一个答案中,当您创建自己的实现时ListModel,在加载要调用的数据时:

fireIntervalAdded(Object source,int index0, int index1)

假设您正在将数据增量加载到列表中。这将导致将JList其用作模型的更新。

请参阅Javadoc 了解 fireIntervalAdded

于 2009-05-12T20:33:54.180 回答
1

不正确。上面的 JList 不是延迟加载的。

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

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

这发生在我运行 Mac OS X 10.6.2 和 Java 的 MacBook 一体机上:

“1.6.0_17”Java(TM) SE 运行时环境(内部版本 1.6.0_17-b04-248-10M3025) Java HotSpot(TM) 64 位服务器 VM(内部版本 14.3-b01-101,混合模式)

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

-鳍-

于 2010-03-28T09:19:59.410 回答