自定义TableModel中的NullPointerException

时间:2012-04-16 19:21:00

标签: java swing jtable nullpointerexception abstracttablemodel

我为JTable写了一个自定义表模型:

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];
    }
}

问题是有一个更新表值的线程,以perodically方式调用setMessages()方法。如果我在此次更新期间尝试获取一行:

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

在这一行:

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

有一种方法可以让方法getMessageAtRow()等待修改完成,或者解决这个问题的其他方法吗?

1 个答案:

答案 0 :(得分:3)

Swing是单线程的。您无法在事件线程之外的线程上修改模型。解决这个问题的最简单方法是:

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()也应仅在事件线程上调用。