开发者

JList throws ArrayIndexOutOfBoundsExceptions randomly

I'm trying to add items to a JList asynchronously but I am regularly getting exceptions from another thread, such as:

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

Does anyone know how to fix this?

(EDIT: I answered this question because it's been bugging me and there is no clear search engine friendly way of finding this info.开发者_JS百科)


Swing components are NOT thread-safe and may sometimes throw exceptions. JList in particular will throw ArrayIndexOutOfBounds exceptions when clearing and adding elements.

The work-around for this, and the preferred way to run things asynchronously in Swing, is to use the invokeLater method. It ensures that the asynchronous call is done when all other requests.

Example using SwingWorker (which implements 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);

Of course you don't need to use a SwingWorker as you can just implement a Runnable instead like this:

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


The model interface is not thread safe. You can only modify the model in EDT.

It is not thread safe because it asks the size separately from the contents.


Are you perhaps modifying it from another thread? Could perhaps be modifying it in the same thread during execution of a JList (or related) method that expects the contents to remain the same size.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜