Очередь JMS в обновление JTable [Теперь получаю исключение после изменений] - PullRequest
0 голосов
/ 26 октября 2009

Я пишу свой собственный JMS-браузер и поражен обновлением JTable сообщений с серверов JMS. Я пытался AbstractTableModel TableModelListener обновить Jtable, когда данные добавлены в LinkedList. Этот логис ниже работает, но не обновляет в реальном времени, означает, что я хотел бы отобразить каждую строку, добавленную в Jtable сразу после его добавления из QueueBrowser в LinkedList.

Я обновил код в соответствии с предложениями ниже.

Я что-то не так делаю? кто-нибудь может мне помочь?

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)

Это неправильно?

Ответы [ 4 ]

1 голос
/ 27 октября 2009

Пара баллов для добавления на рассмотрение:

  • ваш 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);
        }
    });
    
1 голос
/ 26 октября 2009

Насколько мне известно, ваш JTable должен обновляться автоматически при изменении TableModel. Посмотрите учебник sun по , работающему с таблицами , и, в частности, раздел по прослушиванию изменений данных , это может помочь. Тем не менее, у меня есть пара замечаний:

  • Я действительно не понимаю метод getValueAt(int row, int col). Разве вы не должны получить сообщение строки и столбец этого сообщения?

  • Я бы добавил addRow(...) и addRows(...) к реализации MsgTable TableModel для обновления внутренней модели и запуска соответствующего события.

  • Вам не нужно вводить TableModelListener (я все равно не вижу никакого вызова addTableModelListener(...))

(РЕДАКТИРОВАТЬ: ОП обновил свой вопрос новым кодом, поэтому я соответствующим образом обновляю свой ответ ниже.)

Вы изменили подпись и тело load(...), чтобы добавить вызов к addTableModelListener(...), и я думаю, что обе модификации неверны.

О addTableModelListener (...) , документация гласит:

Добавляет слушателя в список, который уведомляется каждый раз, когда происходит изменение модели данных.

И о различных fireFooXxx(...) методах:

Уведомляет всех слушателей, что [произошло изменение]

То есть со следующей реализацией TableModelListener:

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

Вы в конечном итоге будете делать бесконечные рекурсивные вызовы (слушатель уведомляется об изменении и запускает событие, которое уведомит его снова и т. Д.), Следовательно, java.lang.StackOverflowError .

На самом деле, я все еще думаю, что вам не нужен TableModelListener (и то, как вы регистрируете его, не является правильным IMO, см. Прослушивание изменений данных в руководстве Sun). Таким образом, я бы удалил implements TableModelListener и реализовал бы метод load(...) следующим образом:

void load(Enumeration e) {
    while(e.hasMoreElements()) {
        queueList.add(e.nextElement());
    }
    fireTableDataChanged();   
}
0 голосов
/ 26 октября 2009

Что ж, правильный дизайн - создать метод addRow (...), который получает строку данных и обновляет внутреннее хранилище вашей TableModel. Этот метод должен затем вызвать метод fileTableRowsInserted (). Ваш метод getValueAt () также не имеет смысла. Согласно вашей модели у вас есть 5 столбцов данных, но вы никогда не проверяете переменную столбца, чтобы получить правильный объект столбца.

Взгляните на исходный код DefaultTableModel, чтобы увидеть, как могут быть закодированы методы insertRow () и getValueAt ().

0 голосов
/ 26 октября 2009

Одним из способов повышения производительности будет вызов только fireTableDataChanged () в конце метода load (), а не после каждой строки.

это должно помочь.

есть:

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

        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...