2010-12-28 3 views
2

ファイルの内容をJListコンポーネントにロードしています。メインスレッドでロードすると、すべてが正常であるように見えます。コンテンツがロードされています。しかし、コードを読み込んで別のスレッドに移動し、リスト内の項目を選択してリストをリロードしようとすると、ランダムなNullPointerまたはIndexOutOfBounds例外が発生します。私はこれが何らかのSwingスレッドの問題だと確信していますが、何を決定することはできません。JList setListDataスレッドの問題

これは私のスレッドコードです:

@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

Swingコンポーネントに関連するほとんどすべての操作がEDT上で行われなければならないことがありますか? – SyntaxT3rr0r

答えて

4

通常、スイングコンポーネントはスレッドセーフではありません。これは、Swingのワーカースレッドが任意の変更を行う必要があることを意味します

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

も参照してください:

2

スイングはスレッドセーフではありませんので、あなたがしているとき他のスレッドからGUI要素を操作すると、奇妙なことが起こることがあります。あなたのケースでは、最も簡単な解決策(おそらく最高ではないでしょう)を使用することになります