Invalid Range - Fehler bei TableRowSorter / Tabelle

Status
Nicht offen für weitere Antworten.

Taste

Bekanntes Mitglied
Hallo,
ich folgendes Problem:

Ich habe eine Tabelle, der ich ein Model und ein ColumnModel verpasse und soweit ist auch alles gut.
Nun habe ich versucht, anhand der Beispiele in den FAQ's eine Sortierung zu aktivieren:
Code:
         TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>( this.table.getModel() );
          this.table.setRowSorter( sorter );
Eigentlich ja kein Problem. Aber wenn ich dann Daten einfügen möchte mit:
Code:
           final Vector v = new Vector();
            v.add( entry.getKey() );
            v.add( entry.getValue() );
            extMappingTable.getComponent().addRow( v );
Dann erhalte ich folgende Fehlermeldung:

Caused by: java.lang.IndexOutOfBoundsException: Invalid range
at javax.swing.DefaultRowSorter.checkAgainstModel(DefaultRowSorter.java:904)
at javax.swing.DefaultRowSorter.rowsInserted(DefaultRowSorter.java:844)
at javax.swing.JTable.notifySorter(JTable.java:4208)
at javax.swing.JTable.sortedTableChanged(JTable.java:4056)
at javax.swing.JTable.tableChanged(JTable.java:4333)
at com.test.wswing.WJTable.tableChanged(WJTable.java:236)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:280)
at javax.swing.table.AbstractTableModel.fireTableRowsInserted(AbstractTableModel.java:215)
at com.test.client.table.HyperTableModel2.addRow(HyperTableModel2.java:261)
at ...

Instanziiere und setze ich den TableRowSorter nach dem Hinzufügen der Rows, dann klappts problemlos, aber ich will doch eigentlich eine saubere Initialisierung der Tabelle haben, bevor ich Daten einfüge.

Hab ich da einen Gedankenfehler, oder was mache ich falsch?
Gruß, Nick
 
Hallo André,

mein Fehler, Deine Erwartung passt schon.
Diese Methode:
Code:
extMappingTable.getComponent().addRow(v);
ruft auf dem TableModel addRow(...) auf.

Dass das TableModel noch nicht existieren könnte war auch eine Vermutung von mir, aber wenn ich mir direkt an dieser Stelle, wo ich den sorter setze
Code:
tabelModel.getRowCount()
aufrufe, dann bekomme ich 0 zurück und nicht etwa eine NPE.

Ich bekomme die Exception ja auch nicht beim Erzeugen und setzen des RowSortes, sondern beim Einfügen der Daten...

---------------------------------

Ich habe nun testhalber mal Folgendes implementiert:
Code:
// erst Daten setzen
final Vector v = new Vector();
v.add( entry.getKey() );
v.add( entry.getValue() );
extMappingTable.getComponent().addRow(v);

// dann Sorter erzeugen und setzen 
extMappingTable.getComponent().addRow( v );
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>( this.table.getModel() );
          this.table.setRowSorter( sorter );
Dies funktioniert, aber ist ja wie schon gesagt in meinen Augen nicht ganz die richtige Reihenfolge, oder?
Wenn ich dann direkt danach eine weitere Zeile hinzufüge, dann erhalte ich wieder die gleiche Exception:
Code:
// eine weitere Zeile Daten setzen
final Vector v = new Vector();
v.add( entry.getKey() );
v.add( entry.getValue() );
extMappingTable.getComponent().addRow(v);

Was mag da falsch sein...
Herzlichen Gruß, Nick
 
André Uhres hat gesagt.:
"this.table.getModel()" könnte, wenn es denn nicht null ist, auf eine andere Instanz zeigen als "extMappingTable.getComponent()".
TableModel kann nach Erzeugung der Tabelle nicht null sein. JTable Source Code:
Code:
public void setModel(TableModel dataModel) {
  if (dataModel == null) {
        throw new IllegalArgumentException("Cannot set a null TableModel");
  }
[...]
 
Ja, ihr habt beide Recht (nur fürs Ego :wink🙂

Nur leider ist es die gleiche Instanz. Ich hatte bloß den Code nicht mehr genau im Kopf. Ich greife schon direkt auf das Model der Tabelle zu, die ich da mit Daten befülle... Sorry, dass ich mich so missverständlich ausgedrückt habe.

Ich werde mich dem Problem morgen nochmal widmen.

Gruß, Nick

[Edit: Es ist doch leider wirklich die gleiche Instanz 😱)]
 
Zeig mal den Source-Code von HyperTableModel2. Ich gehe davon aus, Du sendest den Event an der falschen Stelle oder zählst RowCount an der falschen Stelle hoch, oder ähnliches.
 
André Uhres hat gesagt.:
Es ist wohl eher so, daß wir zwei verschiedene Instanzen von TableModels haben :wink:
Den letzten Kommentar von Taste hatte ich falsch gelesen... Hatte verstanden, es wären die gleichen Instanzen. 😳
 
Also nun hab ich wieder einige Zeit debugged und Folgendes herausgefunden:

Es handelt sich definitiv um die selbe Instanz von dem Model.

Was fehl schlägt ist diese Methode in DefaultRowSorter:
Code:
private void checkAgainstModel(int firstRow, int endRow) {
        if (firstRow > endRow || firstRow < 0 || endRow < 0 ||
                firstRow > modelRowCount) {
            throw new IndexOutOfBoundsException("Invalid range");
        }
    }
Hier den gesamten Code des Models zu posten wäre wohl zuviel, aber diese Methode macht mich stutzig:
Code:
public void addRow( List aRowData )
   {
      List theRowData = ( aRowData != null ? aRowData : this.createEmptyRow() );
      this.myData.add( theRowData );
      this.fireTableRowsInserted( this.getRowCount(), this.getRowCount() );
   }
this.myData ist einfach nur eine lokale Liste und this.getRowCount() liefert nur die Länge dieser Liste...
Ich versuche nun zu verstehen, wo da überhaupt die Verbindung zur Tabelle ist... Kann doch eigentlich nur über die Methode this.fireTableRowsInserted(...) gehen, oder?

Achso, das Model ist abgeleitet von AbstractTableModel, falls das Euch hilft.
Habt Ihr eine Idee für mich oder könnt mir das erklären?
 
Taste hat gesagt.:
Code:
public void addRow( List aRowData )
   {
      List theRowData = ( aRowData != null ? aRowData : this.createEmptyRow() );
      this.myData.add( theRowData );
      this.fireTableRowsInserted( this.getRowCount(), this.getRowCount() );
   }
Deine letzte Zeile ist nicht bei getRowCount(), sondern bei getRowCount() - 1.

Dann geht's, stimmt's?

PS: Herr Uhres, ich liebe es, wenn ich recht habe :lol:

Ebenius
 
Schon möglich, dass Du Recht hast. 😀
Mir ist noch eingefallen, dass nur diese Bedingung erfüllt sein kann:
Code:
firstRow > modelRowCount
Daher muss die Exception kommen.

Wie meinst Du das mit getRowCount() - 1?
Ich stehe wohl auf dem berühmt berüchtigten Schlauch...
Gruß, Nick
 
Richtig funktioniert es damit:
Code:
public void addRow( List aRowData ) { 
      List theRowData = ( aRowData != null ? aRowData : this.createEmptyRow() ); 
      this.myData.add( theRowData ); 
      this.fireTableRowsInserted( this.getRowCount() - 1, this.getRowCount() - 1 ); 
}

Oder damit:
Code:
public void addRow( List aRowData ) { 
      List theRowData = ( aRowData != null ? aRowData : this.createEmptyRow() );
      final int oldRowCount = this.getRowCount();
      this.myData.add( theRowData ); 
      this.fireTableRowsInserted( oldRowCount, oldRowCount ); 
}

Jetzt klar?

Ebenius
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben