2012-04-16 10 views
0

私はJTableのためのカスタム・テーブル・モデルに書いた:問題はperodically setMessages()メソッドを呼び出して、テーブル値を更新したスレッドがあるということですカスタムTableModel内でのNullPointerException

class MessageTableModel{ 

    private static Set<Message> messages = Collections.synchronizedSet(new TreeSet<Message>()); 

    . 
    . 
    . 

    public void setMessages(List<Message> newMessages) { 
     Collections.sort(newMessages); 
     Iterator<Message> it = messages.iterator(); 
     while (it.hasNext()) { 
      Message mess = it.next(); 
      if (!newMessages.contains(mess)) { 
       it.remove(); 
       this.fireTableDataChanged(); 
      } 
     } 
     for (Message message : newMessages) 
      if (message.isOrderStatusMessage()) 
       if (!messages.contains(message)) { 
        addMessage(message); 
       } 
     this.fireTableDataChanged(); 
    } 

    public Message getMessageAtRow(int row){ 
     return (Message) messages.toArray()[row]; 
    } 
} 

を。私はこのアップデート中の行を取得しようとした場合:

この行の
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 

return (Message) messages.toArray()[row]; 

方法getMessageAtRowを(作るための方法があります)に行われる修正を待ち、または別のソリューションこの問題のために?

答えて

3

スイングはシングルスレッドです。イベントスレッド外のスレッドでモデルを変更することはできません。この問題を解決する最も簡単な方法は、次のようになります。

また
public void setMessages(List<Message> newMessages) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      Collections.sort(newMessages); 
     Iterator<Message> it = messages.iterator(); 
     while (it.hasNext()) { 
      Message mess = it.next(); 
      if (!newMessages.contains(mess)) { 
       it.remove(); 
       this.fireTableDataChanged(); 
      } 
     } 
     for (Message message : newMessages) 
      if (message.isOrderStatusMessage()) 
       if (!messages.contains(message)) { 
        addMessage(message); 
       } 
     this.fireTableDataChanged(); 
    } 
)}; 
} 

fireTableDateChanged()も唯一のイベントスレッド上で呼び出されなければなりません。

+2

詳細については、[同時実行性](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)を参照してください。 –

+0

実際には、問題は、メソッドtable.getSelectedRow() は時々-1を返しますが、私は理由を知らないと考えています... – elias

+1

@Elias 'if(table.getSelectedRow() != -1) ' – mKorbel

関連する問題