有没有一种方法可以在Swing的JList中实现延迟加载?
在某种程度上,是的。您可以创建一个自定义的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; }
};
// 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);
http://java.sun.com/javase/6/docs/api/javax/swing/JList.html#prototype_example
补充一下其他答案的内容,当您创建自己的ListModel
实现时,加载数据时需要调用:
fireIntervalAdded(Object source,int index0, int index1)
JList
进行更新。不正确。上面的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
-完-