2013-12-18 20 views
2

我嘗試在Swing中動態加載JList的內容,以便僅從某處(數據庫,文件系統,rpc調用)加載顯示的內容。下面的代碼沒有實現這個動作,因爲它對於顯示問題並不重要。在Swing中使用SwingWorker需要延遲加載jList Thread.sleep()

所以我實現我自己的名單模型類:

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()調用,這是不僅是黑客?我不明白爲什麼要爲所有值調用getElementAt(index)

P.S:由於更新了在doInBackground()方法中計算的值,因此列表模型僅傳遞給擺動工作人員類。

回答

1

多次調用getElementAt()是因爲列表的大小爲500個元素指定,並且列表遍歷這些元素。從javax.swing.plaf.basic.BasicListUI中

來源:

for(int index = 0; index < dataModelSize; index++) { 
    Object value = dataModel.getElementAt(index); 
... 

不過,我建議看看Glazed Lists。如果你想更新給定索引的元素,你可以使用EventList。

「......你可以從一個線程填充您的EVENTLIST從另一個讀取它。對於GUI應用程序,你可以填充你的EVENTLIST在後臺線程同時使用用戶界面線程安全地瀏覽它。」

看看tutorial,問題瀏覽器可能與您的使用情況類似。

+0

何時何地我應該調用swing worker對象?此外......如何僅在調用一次時將當前索引傳遞給swing工作人員? – sk2212

+0

想知道一個問題:是不是從列表代表中檢索元素的索引? – Spindizzy

+0

正確。我在後臺任務的給定索引處更新列表中的元素。 – sk2212