我正在编写自己的JMS浏览器,并对来自JMS服务器的消息的JTable更新感到震惊。当数据添加到LinkedList中时,我尝试过AbstractTableModel TableModelListener使Jtable刷新。下面的逻辑可以正常工作,但是不能实时更新,这意味着当它从QueueBrowser添加到LinkedList时,我想立即显示添加到Jtable的每一行。

我已经按照以下建议更新了代码。

难道我做错了什么?谁能帮我 ?

QueueBrowser qb = session.createBrowser(q);
MsgTable mt = (MsgTable) queueTable.getModel();
mt.load(qb.getEnumeration(),mt);
qb.close();




 class MsgTable extends AbstractTableModel implements TableModelListener{


      final String[] columnNames = { "#", "Timestamp", "Type", "Mode",
        "Priority" };

      public void setRowSize(){

      }
      LinkedList queueList = new LinkedList();

      public int getRowCount() { if (queueList == null) { return 0; } else { return queueList.size();}}
      public int getColumnCount() { return columnNames.length;}
      public String getColumnName(int column) {return columnNames[column];}

      public Object getValueAt(int row, int column) {
       if(queueList == null){
        return null;
       }
                        Message m = (Message) queueList.get(row);
                        ...
      }

      void load(Enumeration e,MsgTable mt) {
                         mt.addTableModelListener(this);
        while(e.hasMoreElements()){
         queueList.add(e.nextElement());

        }
                      fireTableDataChanged();
      }

      Message getMessageAtRow(int row) {
       if (queueList == null)
        return null;
       return ((Message) queueList.get(row));
      }

                @Override
  public void tableChanged(TableModelEvent arg0) {
   // TODO Auto-generated method stub
   fireTableDataChanged();
  }

}


并获得此异常。

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError  at javax.swing.table.AbstractTableModel.fireTableRowsInserted(Unknown Source)


这是错的吗 ?

最佳答案

据我所知,JTable发生更改时,您的TableModel应该会自动更新。查看working with tables上的sun教程,特别是listening for data changes上的部分,这可能会有所帮助。也就是说,我有几点要点:


我真的没有得到getValueAt(int row, int col)方法。您是否不应该获得该消息的第行消息和第col属性?
我将为TableModel的addRow(...)实现添加addRows(...)MsgTable来更新内部模型并触发适当的事件。
您无需实现TableModelListener(无论如何我都看不到对addTableModelListener(...)的任何调用)


(编辑:OP用新代码更新了他的问题,因此我在下面相应地更新了我的答案。)

您已经修改了load(...)签名和正文以添加对addTableModelListener(...)的调用,我认为这两种修改都不正确。

关于addTableModelListener(...),文档说:


  将侦听器添加到每次数据模型发生更改时都会通知的列表。


关于各种fireFooXxx(...)方法:


  通知所有侦听器[发生了更改]


因此,使用TableModelListener的以下实现:

@Override
public void tableChanged(TableModelEvent arg0) {
    // TODO Auto-generated method stub
    fireTableDataChanged();
}


您最终将进行无限次递归调用(更改将通知侦听器并触发将再次通知他的事件,依此类推),因此就是java.lang.StackOverflowError

实际上,我仍然认为您不需要TableModelListener(并且注册它的方式不是正确的IMO,请参见Sun教程中的Listening for Data Changes)。因此,我将删除implements TableModelListener,而是像这样实现load(...)方法:

void load(Enumeration e) {
    while(e.hasMoreElements()) {
        queueList.add(e.nextElement());
    }
    fireTableDataChanged();
}

10-05 23:28