我試圖將項目添加到一個JList異步,但我經常從另一個線程獲取例外,如:JList的拋出ArrayIndexOutOfBoundsExceptions隨機
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 8
有誰知道如何解決這一問題?
(編輯:我回答這個問題,因爲它是被竊聽我並沒有發現這個信息沒有明確的搜索引擎友好的方式)
我試圖將項目添加到一個JList異步,但我經常從另一個線程獲取例外,如:JList的拋出ArrayIndexOutOfBoundsExceptions隨機
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 8
有誰知道如何解決這一問題?
(編輯:我回答這個問題,因爲它是被竊聽我並沒有發現這個信息沒有明確的搜索引擎友好的方式)
Swing組件是不是線程安全的並且有時可能會拋出異常。清理和添加元素時,JList尤其會拋出ArrayIndexOutOfBounds exceptions。
解決此問題的方法以及在Swing中異步運行事件的首選方法是使用invokeLater
method。它確保在所有其他請求時完成異步調用。
例使用SwingWorker
(實現Runnable
):
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
Collection<Object> objects = doSomethingIntense();
this.myJList.clear();
for(Object o : objects) {
this.myJList.addElement(o);
}
return null;
}
}
// This WILL THROW EXCEPTIONS because a new thread will start and meddle
// with your JList when Swing is still drawing the component
//
// ExecutorService executor = Executors.newSingleThreadExecutor();
// executor.execute(worker);
// The SwingWorker will be executed when Swing is done doing its stuff.
java.awt.EventQueue.invokeLater(worker);
當然你不需要使用SwingWorker
因爲你可以實現一個Runnable
,而不是像這樣:
// This is actually a cool one-liner:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Collection<Object> objects = doSomethingIntense();
this.myJList.clear();
for(Object o : objects) {
this.myJList.addElement(o);
}
}
});
你或許從另一個線程修改呢?在執行期望內容保持相同大小的JList
(或相關)方法期間,可能可能會在同一個線程中修改它。
模型接口不是線程安全的。您只能修改EDT中的模型。
它不是線程安全的,因爲它要求的大小與內容分開。
提供更多有關您如何將項目添加到此列表的信息。你使用自己的模型? – Gnoupi 2010-08-09 13:23:44
啊。我自己會回答這個問題,因爲我已經在這個問題上呆了好幾個小時,查找它(在這裏插入你最喜歡的搜索引擎)。 – Spoike 2010-08-09 13:37:36
@spoike - 在這種情況下,我建議你在問題中已經說過,或者已經在旁邊輸入答案,以避免人們急於回答問題,無論如何你都會回答問題。 – Gnoupi 2010-08-09 13:49:01