【问题标题】:Is there a lazy loading implementation of JList?JList 有延迟加载实现吗?
【发布时间】:2010-10-25 14:06:05
【问题描述】:

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

【问题讨论】:

    标签: java swing jlist


    【解决方案1】:

    在某种程度上,是的。您可以创建一个自定义 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; }
    };
    

    【讨论】:

    • 感谢您的回答,我试过了,它让我意识到我的界面很慢,因为有人编写和使用了自定义“排序”列表模型
    【解决方案2】:

    我解决了。我错过了 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

    【讨论】:

    • 谢谢你——我也错过了。
    【解决方案3】:

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

    fireIntervalAdded(Object source,int index0, int index1)
    

    假设您以增量方式将数据加载到列表中。这将导致将其用作模型的JList 进行更新。

    Javadoc for fireIntervalAdded

    【讨论】:

    • 嗯,我想知道为什么这个例子没有这样做。也许它更美观(保持滚动条同步)。
    • 也非常感谢,我在自定义列表模型中实现“addAll”方法时使用了它
    【解决方案4】:

    不正确。上面的 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 位服务器虚拟机(构建 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
    

    -fin-

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多