我正在尝试异步向JList添加项目,但我经常从另一个线程获取异常,例如:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 8
有谁知道如何解决这个问题?
(编辑:我回答了这个问题,因为它一直在困扰我,并且没有明确的搜索引擎友好的方式来查找此信息。)
答案 0 :(得分: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);
}
}
});
答案 1 :(得分:3)
模型接口不是线程安全的。您只能在EDT中修改模型。
它不是线程安全的,因为它与内容分开询问大小。
答案 2 :(得分:0)
你是否可以从另一个线程修改它?在执行期望内容保持相同大小的JList
(或相关)方法时,也许可以在同一个线程中修改它。