[英]Lazy loading of jList in Swing with SwingWorker needs Thread.sleep()
我嘗試在Swing中動態加載JList的內容,以便僅從某處(數據庫,文件系統,rpc調用)加載顯示的內容。 下面的代碼不執行此操作,因為它對於顯示問題並不十分重要。
因此,我實現了自己的列表模型類:
class ServiceListModel extends AbstractListModel {
private final static int MYSIZE = 500;
private final List<String> delegate = new ArrayList<String>();
public ServiceListModel() {
// Init with dummy content
for(int i=0;i<MYSIZE;i++) {
delegate.add("Loading...");
}
}
@Override
public int getSize() {
return delegate.size();
}
@Override
public Object getElementAt(int index) {
new DoSomeThingClass(index, this).execute();
}
private class DoSomeThingClass extends SwingWorker<String, String> {
private int index;
private ServiceListModel model;
public DoSomeThingClass(int index, ServiceListModel model) {
this.index = index;
this.model = model;
}
@Override
protected String doInBackground() throws Exception {
System.out.println("BACKGROUND: " + index);
// Do some stuff for updating content in JList
return "";
}
@Override
protected void process(java.util.List<String> list) {
for(String s: list) {
}
}
@Override
protected void done() {
System.out.println("INDEX: " + index);
}
}
}
在JList中設置模型:
jList1.setModel(new ServiceListModel());
現在的問題是,如果我快速滾動到JList內容的末尾,那么所有值仍然在方法getElementAt(index)
中計算,而不僅是JList內容的末尾。 所有索引值都顯示在系統輸出控制台中。
為了解決該問題,需要在調用Swing Worker類之前在getElementAt(index)
添加Thread.sleep(20)。
題:
為什么我需要這個Thread.sleep()調用,這不僅是hack嗎? 我不明白為什么要為所有值調用getElementAt(index)
。
PS:由於更新了在doInBackground()
方法中計算的值,因此列表模型僅傳遞給swing工人類。
由於為500個元素指定了列表的大小,因此getElementAt()被多次調用,並且列表在這些元素上進行迭代。
來自javax.swing.plaf.basic.BasicListUI的源:
for(int index = 0; index < dataModelSize; index++) {
Object value = dataModel.getElementAt(index);
...
但是,我建議看看“ 釉面表” 。 如果要更新給定索引處的元素,則可以使用EventList。
“ ...您可以從一個線程填充EventList並從另一個線程讀取它。對於GUI應用程序,您可以在后台線程中填充EventList,同時使用用戶界面線程安全地瀏覽它。
查看教程 ,問題瀏覽器可能與您的用例相似。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.