JMS 队列到 JTable 更新 [现在在更改后出现异常]
我正在编写自己的 JMS 浏览器,并且对来自 JMS 服务器的消息的 JTable 更新感到震惊。 我尝试过下面的逻辑有效,但它不实时更新,意味着我希望在从 QueueBrowser 添加到 LinkedList 时立即显示添加到 Jtable 的每一行。AbstractTableModel
TableModelListener
在数据添加到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 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.AbstractTableModel
TableModelListener
to make Jtable refresh when the data added into 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
需要添加几点供考虑:
load(Enumeration e)
方法不需要抛出JMSException
,因为您只是迭代Enumeration
代码>.您应该确保事件触发是在 EDT 内完成的。这可能很简单,只需将对
load
的调用包装在可运行的文件中并将其放入SwingUtilities.invokeLater()
中即可:A couple points to add for consideration:
load(Enumeration e)
method does not need to throw aJMSException
, as you are just iterating over anEnumeration
.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 intoSwingUtilities.invokeLater()
:提高性能的一种方法是仅在 load() 方法末尾调用 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:
to
那么,正确的设计是创建一个 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.
据我所知,当
TableModel
发生更改时,您的JTable
应该会自动更新。查看关于使用表的 sun 教程特别是监听数据更改部分,这可能有帮助。也就是说,我有几点意见:我并没有真正理解
getValueAt(int row, int col)
方法。难道你不应该得到第 row-th 消息和消息的第 col-th 属性吗?我会向 TableModel 的
MsgTable
实现添加addRow(...)
和addRows(...)
来更新内部模型并触发适当的事件。您不需要实现
TableModelListener
(无论如何,我看不到任何对addTableModelListener(...)
的调用)(编辑:OP 已用新代码更新了他的问题,所以我'我在下面相应地更新了我的答案。)
您已经修改了
load(...)
签名和正文以添加对addTableModelListener(...)
的调用,我认为两种修改都不正确。关于 addTableModelListener(...),文档说:
关于各种
fireFooXxx(...)
方法:因此,使用以下
TableModelListener
实现:您最终将进行无限递归调用(侦听器收到更改通知并触发一个事件来通知他再次等),因此 java.lang.StackOverflowError< /a>.
实际上,我仍然认为您不需要
TableModelListener
(并且您注册它的方式在我看来是不正确的,请参阅 监听数据更改)。因此,我将删除implements TableModelListener
并实现load(...)
方法,如下所示:To my knowledge, your
JTable
should update automatically when a change to theTableModel
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(...)
andaddRows(...)
toMsgTable
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 toaddTableModelListener(...)
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 toaddTableModelListener(...)
and I think that both modifications are not correct.About the addTableModelListener(...), the documentation says:
And about the various
fireFooXxx(...)
methods:So with the following implementation of a
TableModelListener
: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 theimplements TableModelListener
and rather implement theload(...)
method like this: