Проблемы с потоками в JList setListData - PullRequest
2 голосов
/ 28 декабря 2010

Я загружаю содержимое файла в JList компонент.Если я делаю загрузку в основном потоке, все вроде бы нормально - содержимое загружается.Но когда я перемещаю код загрузки в отдельный поток, выбираю элемент в списке и пытаюсь перезагрузить список, я получаю случайные NullPointer или IndexOutOfBounds исключения.Я уверен, что это какая-то проблема с потоками Swing, но не могу определить, что.

Это мой код потока:

@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
}

Контроллер отвечает за прослушивание:

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

И вид обновляется:

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

Я пытался оставить поток зависшим, добавив цикл while(true); - тогда все работает нормально.Если я нажму "Перезагрузить", не выбрав элемент в списке, все тоже будет работать.

Может кто-нибудь объяснить, что мне здесь не хватает?

Ответы [ 2 ]

4 голосов
/ 28 декабря 2010

Компоненты Swing обычно не являются поточно-ориентированными. Это означает, что только рабочий поток Swing должен выполнять любые изменения:

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

Смотри также:

2 голосов
/ 28 декабря 2010

Swing не является потокобезопасным, поэтому, когда вы манипулируете элементами GUI из других потоков, может произойти много странных вещей. В вашем случае самое простое решение (но, вероятно, не самое лучшее) будет использовать SwingUtilities.invokeLater

...