Frage

ich meinen eigenen JMS-Browser schreibe, und ich bin an der JTable Aktualisierung von Nachrichten von JMS-Server getroffen. Ich habe AbstractTableModel TableModelListener versucht jtable refresh zu machen, wenn die Daten in LinkedList hinzugefügt. Das unten Logis funktioniert, aber es ist nicht die Aktualisierung in Echtzeit bedeutet würde Ich mag jede einzelne Zeile zu jtable hinzugefügt sofort, wenn angezeigt werden seine hinzugefügt von QueueBrowser zu LinkedList.

Ich habe den Code gemäß den nachstehenden Empfehlungen aktualisiert.

Mache ich etwas falsch? kann mir jemand helfen?

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

}

und diese Ausnahme zu bekommen.

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

Ist es falsch?

War es hilfreich?

Lösung

Meines Wissens sollte Ihr JTable automatisch aktualisiert, wenn eine Änderung der TableModel passiert. Schauen Sie sich die Sonne Tutorial auf Arbeit mit Tabellen und speziell der Abschnitt hören für Datenänderungen kann dabei helfen. Das heißt, ich habe ein paar Bemerkungen:

  • Ich habe nicht wirklich die getValueAt(int row, int col) Methode. Sollten Sie nicht die Zeile-ten Nachricht erhalten und das col-te Attribut der Nachricht?

  • Ich würde eine addRow(...) und addRows(...) hinzufügen Implementierung von Tablemodel MsgTable des internen Modells zu aktualisieren und das entsprechende Ereignis aus.

  • Sie brauchen nicht TableModelListener zu implementieren (ich keinen Anruf sehen sowieso addTableModelListener(...))

(EDIT:. Die OP wird aktualisiert seine Frage mit neuem Code, damit ich entsprechend unter meiner Antwort bin Aktualisierung)

Sie haben die load(...) Unterschrift und Körper modifiziert, um einen Anruf hinzufügen, um addTableModelListener(...) und ich denke, dass beide Modifikationen, die nicht korrekt sind.

Über die addTableModelListener (... ), die Dokumentation sagt:

  

Fügt einen Listener zu der Liste, die jedes Mal, wenn eine Änderung auftritt, auf das Datenmodell benachrichtigt wird.

Und über die verschiedenen fireFooXxx(...) Methoden:

  

Benachrichtigt alle Zuhörer, dass [eine veränderte aufgetreten]

So mit der folgenden Implementierung eines TableModelListener:

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

Sie werden unendlich rekursive Anrufe am Ende machen (der Hörer durch eine Änderung informiert wird und ein Ereignis ausgelöst, die ihn wieder usw. mitteilen werden), damit die java.lang.StackOverflowError .

Eigentlich, denke ich immer noch, dass Sie brauchen keine TableModelListener (und so, wie Sie es sind Registrierung nicht IMO korrekt ist, finden Sie unter für Daten Zuhören Änderungen in den Sun-Tutorial). Ich würde so die implements TableModelListener entfernen und lieber die load(...) Methode wie folgt implementieren:

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

Andere Tipps

Ein paar Punkte zur Prüfung hinzuzufügen:

  • Ihre load(Enumeration e) Methode benötigt keine JMSException zu werfen, wie Sie gerade über einen Enumeration iterieren.
  • Sie sollten sicherstellen, dass Ihre Abfeuern von Ereignissen innerhalb des EDT erfolgt. Dies könnte so einfach sein wie Ihren Anruf Einwickeln in einem runnable load und in SwingUtilities.invokeLater() fallen:

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

Ein Weg, um die Leistung bis zu nur nennen fireTableDataChanged wäre () am Ende der Last () Methode, im Gegensatz zu nach jeder Zeile geladen wird.

das sollte helfen.

ie:

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

        }

Nun, das ist die richtige Gestaltung eines addRow (...) Methode zu erstellen, die eine Reihe von Daten empfängt und aktualisiert die interne Speicherung Ihrer Tablemodel. Diese Methode sollte dann die fileTableRowsInserted () -Methode aufrufen. Ihre getValueAt () -Methode macht auch keinen Sinn. Nach Ihrem Modell haben Sie 5 Spalten von Daten, aber Sie überprüfen nie die Spaltenvariable die richtige Spalte Objekt zurück.

Werfen Sie einen Blick auf den Quellcode des DefaultTableModel zu sehen, wie ein insertRow () und getValueAt () -Methode können codiert werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top