我正在编写自己的 JMS 浏览器,并且对来自 JMS 服务器的消息的 JTable 更新感到震惊。 我努力了 AbstractTableModel TableModelListener 当数据添加到LinkedList时使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 发生。查看太阳教程 使用表格 特别是关于 监听数据变化, ,这可能有帮助。话虽如此,我有几点评论:

  • 我真的不明白 getValueAt(int row, int col) 方法。难道您不应该获取该消息的第 row 消息和 col-th 属性吗?

  • 我想添加一个 addRow(...)addRows(...)MsgTable 实现 TableModel 来更新内部模型并触发适当的事件。

  • 你不需要实施 TableModelListener (我看不到任何呼叫 addTableModelListener(...) 反正)

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

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

有关 添加TableModelListener(...), ,文档说:

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

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

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

因此,通过以下实现 TableModelListener:

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

您最终将进行无限递归调用(监听器收到更改通知并触发一个事件再次通知他等),因此 java.lang.StackOverflowError 错误.

其实我还是觉得你不需要 TableModelListener (并且您注册的方式在我看来是不正确的,请参阅 监听数据变化 在 Sun 教程中)。因此我会删除 implements TableModelListener 而是实施 load(...) 像这样的方法:

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

其他提示

需要补充几点供考虑:

  • 你的 load(Enumeration e) 方法不需要抛出 JMSException, ,因为您只是迭代 Enumeration.
  • 您应该确保您的事件触发是在 EDT 内完成的。这可能就像将您的呼叫包装到 load 在可运行的并将其放入 SwingUtilities.invokeLater() :

    MsgTable mt = (MsgTable) queueTable.getModel();
    final Enumeration e = qb.getEnumeration();
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            mt.load(e);
        }
    });
    

提高性能的一种方法是仅在load()方法结束时调用fireTableDataChanged(),而不是在每行加载之后调用。

应该有所帮助。

即:

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

void load(Enumeration e) throws JMSException {
                 boolean dataAdded = false;
                 while(e.hasMoreElements()){
                         queueList.add(e.nextElement());
                         dataAdded = true;
                     }
                 fireTableDataChanged();

        }

嗯,正确的设计是创建一个addRow(...)方法,该方法接收一行数据并更新TableModel的内部存储。然后,此方法应调用fileTableRowsInserted()方法。你的getValueAt()方法也没有意义。根据您的模型,您有5列数据,但您从不检查列变量以返回正确的列对象。

查看DefaultTableModel的源代码,了解insertRow()和getValueAt()方法的编码方式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top