Is there a lazy loading implementation of JList?

巧了我就是萌 提交于 2021-01-27 07:37:53

问题


Is there a way to implement lazy loading with Swing's JList?


回答1:


In a way, yes. You can create a custom ListModel which uses the getElementAt(int index) method to load the correct value if it hasn't already been loaded. See the example in the Javadocs for 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; }
};



回答2:


I solved it. I had missed the solution discussed at the top of the JList API documentation.

In the example source code I posted in another answer on this topic, add this line (and comment) after creating the 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); 

The problem is that JList, by default, is accessing every item in the entire ListModel to determine at runtime the necessary display size. The line added above overrides that default, and tells JList to examine just the one value as passed. That one value acts as a template (prototype) for sizing the display of the JList.

See:

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




回答3:


Just to add to the other answer, when you create your own implementation of ListModel, while you are loading the data you will want to call:

fireIntervalAdded(Object source,int index0, int index1)

Assuming that you are loading data into your list incrementally. This will cause the JList that is using it as a model to update.

See Javadoc for fireIntervalAdded




回答4:


Incorrect. That JList above is NOT lazily loaded.

Swing insists on accessing each item in the entire ListModel while getting it displayed on screen. Furthermore, after accessing all the items, Swing then re-accesses the first n number of items visible on screen (in the viewport, not off screen below).

Run this simple "TestJList" class to prove it. I call println each time 'getElementAt' is executed. You can plainly see that Swing calls that method for every item in the ListModel.

This happens for me on a MacBook unibody running Mac OS X 10.6.2 with 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();
                }
            });
    }
}

Run that code, and you'll see:

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-



来源:https://stackoverflow.com/questions/853168/is-there-a-lazy-loading-implementation-of-jlist

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!