Swing の JList で遅延読み込みを実装する方法はありますか?
4 に答える
ある意味、そうです。まだロードされていない場合ListModel
は、メソッドを使用して正しい値をロードするカスタムを作成できます。getElementAt(int index)
の Javadoc の例を参照してください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; }
};
私はそれを解決しました。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 全体のすべての項目にアクセスして、実行時に必要な表示サイズを決定していることです。上に追加された行は、そのデフォルトをオーバーライドし、渡された 1 つの値だけを調べるように JList に指示します。その 1 つの値は、JList の表示サイズを変更するためのテンプレート (プロトタイプ) として機能します。
見る:
http://java.sun.com/javase/6/docs/api/javax/swing/JList.html#prototype_example
ListModel
の独自の実装を作成するときに、呼び出したいデータをロードしているときに、他の答えに追加するだけです。
fireIntervalAdded(Object source,int index0, int index1)
リストにデータを段階的にロードしていると仮定します。これにより、JList
それをモデルとして使用している が更新されます。
fireIntervalAdded の Javadoc を参照してください
正しくない。上記の JList は遅延ロードされません。
Swing は、画面に表示される間、ListModel 全体の各項目にアクセスすることを主張します。さらに、すべてのアイテムにアクセスした後、Swing は画面上 (以下の画面外ではなくビューポート内) に表示されている最初の n 個のアイテムに再度アクセスします。
この単純な「TestJList」クラスを実行して、それを証明してください。「getElementAt」が実行されるたびにprintlnを呼び出します。Swing が ListModel 内のすべての項目に対してそのメソッドを呼び出していることがはっきりとわかります。
これは、Java で Mac OS X 10.6.2 を実行している 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
-フィン-