2010-08-09 66 views
3

我试图将项目添加到一个JList异步,但我经常从另一个线程获取例外,如:JList的抛出ArrayIndexOutOfBoundsExceptions随机

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 8 

有谁知道如何解决这一问题?

(编辑:我回答这个问题,因为它是被窃听我并没有发现这个信息没有明确的搜索引擎友好的方式)

+0

提供更多有关您如何将项目添加到此列表的信息。你使用自己的模型? – Gnoupi 2010-08-09 13:23:44

+0

啊。我自己会回答这个问题,因为我已经在这个问题上呆了好几个小时,查找它(在这里插入你最喜欢的搜索引擎)。 – Spoike 2010-08-09 13:37:36

+0

@spoike - 在这种情况下,我建议你在问题中已经说过,或者已经在旁边输入答案,以避免人们急于回答问题,无论如何你都会回答问题。 – Gnoupi 2010-08-09 13:49:01

回答

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); 
     } 
    } 
}); 
0

你或许从另一个线程修改呢?在执行期望内容保持相同大小的JList(或相关)方法期间,可能可能会在同一个线程中修改它。

3

模型接口不是线程安全的。您只能修改EDT中的模型。

它不是线程安全的,因为它要求的大小与内容分开。

相关问题