miceuz miceuz - 4 days ago 6
Java Question

JList setListData threading issues

I'm loading contents of a file to

JList
component. If I do the loading in main thread, everything seems to be OK - contents are loaded. But when I move loading code to separate thread, select an item in a list and try to reload the list, I get random
NullPointer
or
IndexOutOfBounds
exceptions. I'm sure this is some kind of Swing threading issue, but can't determine what.

This is my thread code:

@Override
public void run() {
List<String> textLines = null;
textLines = splitter.split(model.getLedMaxChars(), textLoader.loadText(file));
listener.onTextLoaded(textLines);//listener is in main Swing code
}


Controller is responsible for listening:

@Override
public void onTextLoaded(List<String> textLines) {
view.fileLoaded(model.getCurrentFile());
view.setTextLines(textLines);
view.enableListComponent();
}


And the view updates:

public void setTextLines(List<String> textLines) {
jList.setListData(textLines.toArray());
}


I've tried to leave thread to hang by adding
while(true);
loop - then everything works OK. If I hit reload without selecting item in a list, everything works too.

Could anyone explain what I'm missing here?

Answer

Swing components are usually not thread-safe. This means that only the Swing worker thread should do any modifications:

Runnable worker = new Runnable() {  
  public void run() {
     jList.setListData(textLines.toArray());
  } 
};
SwingUtilities.invokeLater(worker);

See also:

Comments