JMS 队列到 JTable 更新 [现在在更改后出现异常]

发布于 2024-08-08 18:23:07 字数 1921 浏览 3 评论 0原文

我正在编写自己的 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)

是不是错了?

I am writing my own JMS Browser and I am struck at the JTable update of Messages from JMS servers. I have tried AbstractTableModel TableModelListener to make Jtable refresh when the data added into LinkedList. This below logis works , but its not updating realtime , means I would like to display each and every row added to Jtable immediately when its added from QueueBrowser to LinkedList.

I have updated the code as per the suggestions below.

Am I doing something wrong? can anyone help me ?

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();
  }

}

and getting this exception.

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

Is it wrong ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

依 靠 2024-08-15 18:23:08

需要添加几点供考虑:

  • 您的 load(Enumeration e) 方法不需要抛出 JMSException,因为您只是迭代 Enumeration代码>.
  • 您应该确保事件触发是在 EDT 内完成的。这可能很简单,只需将对 load 的调用包装在可运行的文件中并将其放入 SwingUtilities.invokeLater() 中即可:

    MsgTable mt = (MsgTable)queueTable.getModel();
    最终枚举 e = qb.getEnumeration();
    SwingUtilities.invokeLater(new Runnable() {
        公共无效运行(){
            mt.load(e);
        }
    });
    

A couple points to add for consideration:

  • your load(Enumeration e) method does not need to throw a JMSException, as you are just iterating over an Enumeration.
  • you should ensure that your firing of events is done within the EDT. This could be as simple as wrapping your call to load in a runnable and dropping it into SwingUtilities.invokeLater() :

    MsgTable mt = (MsgTable) queueTable.getModel();
    final Enumeration e = qb.getEnumeration();
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            mt.load(e);
        }
    });
    
深海少女心 2024-08-15 18:23:08

提高性能的一种方法是仅在 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();

        }

one way to up performance would be to only call fireTableDataChanged() at the end of the load() method, as opposed to after each line is loaded.

that should help.

ie:

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

to

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

        }
如梦亦如幻 2024-08-15 18:23:08

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

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

Well, the proper design is to create an addRow(...) method that receives a row of data and updates the internal storage of your TableModel. This method should then invoke the fileTableRowsInserted() method. Your getValueAt() method also makes no sense. According to your model you have 5 columns of data, yet you never check the column variable to return the proper column object.

Take a look at the source code of the DefaultTableModel to see how an insertRow() and getValueAt() method might be coded.

喜爱纠缠 2024-08-15 18:23:07

据我所知,当 TableModel 发生更改时,您的 JTable 应该会自动更新。查看关于使用表的 sun 教程特别是监听数据更改部分,这可能有帮助。也就是说,我有几点意见:

  • 我并没有真正理解 getValueAt(int row, int col) 方法。难道你不应该得到第 row-th 消息和消息的第 col-th 属性吗?

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

  • 您不需要实现 TableModelListener (无论如何,我看不到任何对 addTableModelListener(...) 的调用)

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

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

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

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

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

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

因此,使用以下 TableModelListener 实现:

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

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

实际上,我仍然认为您不需要 TableModelListener (并且您注册它的方式在我看来是不正确的,请参阅 监听数据更改)。因此,我将删除 implements TableModelListener 并实现 load(...) 方法,如下所示:

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

To my knowledge, your JTable should update automatically when a change to the TableModel happens. Check out the sun tutorial on working with tables and specially the section on listening for data changes, this may help. That said, I have a couple of remarks:

  • I don't really get the getValueAt(int row, int col) method. Shouldn't you get the row-th message and the col-th attribute of the message?

  • I'd add a addRow(...) and addRows(...) to MsgTable implementation of TableModel to update the internal model and fire the appropriate event.

  • You don't need to implement TableModelListener (I can't see any call to addTableModelListener(...) anyway)

(EDIT: The OP has updated his question with new code so I'm updating my answer accordingly below.)

You've modified the load(...) signature and body to add a call to addTableModelListener(...) and I think that both modifications are not correct.

About the addTableModelListener(...), the documentation says:

Adds a listener to the list that is notified each time a change to the data model occurs.

And about the various fireFooXxx(...) methods:

Notifies all listeners that [a changed occurred]

So with the following implementation of a TableModelListener:

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

You'll end up making infinite recursive calls (the listener is notified by a change and fire an event that will notify him again etc), hence the java.lang.StackOverflowError.

Actually, I still think that you don't need a TableModelListener (and the way you are registering it is not correct IMO, see Listening for Data Changes in the Sun tutorial). I'd thus remove the implements TableModelListener and rather implement the load(...) method like this:

void load(Enumeration e) {
    while(e.hasMoreElements()) {
        queueList.add(e.nextElement());
    }
    fireTableDataChanged();   
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文