Fehler nach erfolgreichem Einfügen neuer Zeilen

Hallo zusammen,

Ich habe eine Methode geschrieben, die mir zu einer bestimmten Baureihe von Getriebe alle zugehörigen Typen, davon alle Größen Stufenzahlen und davon wiederum alle Übersetzungen als Vektoren erstellt und in eine JTable einfügt:

private void addToTable(String baureihe){
		int debug = 0;
		//Alle Getriebetypen der Baureihe auslesen
		ArrayList<String> gTypen = selGetriebe.getAllGetriebetypen();		
		ArrayList<String> gGroessen;
		ArrayList<Integer> gStufen;
		ArrayList<String> gUebersetzung;
		
		//Vektor, welcher als Tabellenreihe angefügt wird
		Vector newRow = new Vector();
		
		for(int i=gTypen.size()-1; i>=0; i--){
			if(!gTypen.get(i).startsWith(baureihe))
				gTypen.remove(i);
		}
		
		System.out.println("Check OK");
		/**Alle Getriebe der gewählten Baureihe werden ausgelesen
		 *
		 * Zunächst werden alle Größe und Stufenzahlen hinzugefügt.
		 * Anschließend die zugehörigen Übersetzungen ausgelesen.
		 */
		
		for(int typ = 0; typ < gTypen.size(); typ++){
					
			gGroessen = selGetriebe.getGroesse(gTypen.get(typ));
			gStufen = selGetriebe.getStufenzahl(gTypen.get(typ));
			
			//Größen- und Stufenzahlschleife
			for(int groesse = 0; groesse < gGroessen.size(); groesse++){
				for(int stufe = 0; stufe< gStufen.size(); stufe++){
					
					gUebersetzung = selGetriebe.getUebersetzung(gTypen.get(typ), gGroessen.get(groesse), gStufen.get(stufe));
					//Schleife der Übersetzungen. Hier wird der Vektor befüllt und sofort hinzugefügt.
					for(int i = 0; i<gUebersetzung.size(); i++){
						newRow.add(gTypen.get(typ));
						newRow.add(gGroessen.get(groesse));
						newRow.add(gStufen.get(stufe));
						newRow.add(gUebersetzung.get(i));
						
						gTableModel.addRow(newRow);
						newRow.removeAllElements();
						debug ++;
						System.out.println("I OK");
					}
					System.out.println("Stufe OK");
				}
				System.out.println("Größe OK");
			}
			
			System.out.println("Typ OK" + gTypen.get(typ));
		}
		
		System.out.println(debug);
		
	}

Was ich nicht verstehe ist folgendes: Die Schleifen laufen ohne Probleme komplett durch und am Ende wird debug angezeigt. Anschließend tritt folgende Exception auf, die ich leider nicht zurückverfolgen kann. Ich habe keine Ahnung, warum dieser Fehler auftritt.

Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
	at java.util.Vector.elementAt(Unknown Source)
	at javax.swing.table.DefaultTableModel.getValueAt(Unknown Source)
	at javax.swing.JTable.getValueAt(Unknown Source)
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JViewport.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.access$700(Unknown Source)
	at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Danach passiert im Code auch nichts mehr, d.h. nach Ende der Methode passiert ohne Aktionen des Users nichts weiter.

Falls es noch etwas hilft hier die Initialisierung der JTable:

//TableModel der Tabelle konfigurieren
		gTableModel = new DefaultTableModel(new String[]{"Typ", "Größe", "Stufen", "i"}, 0){
			public boolean isEditable(int row, int col){
				return false;
			}
		};
		
		//Tabelle erstellen
		JTable gTable = new JTable(gTableModel);
		gTable.setRowHeight(21);
		
		//In JScrollPane einbetten
		JScrollPane gTablePane = new JScrollPane(gTable);
		gTablePane.setOpaque(true);

Meine erste Idee war dass es zu viele Datensätze sind. Daher habe ich “debug” eingefügt, es sind aber immer zwischen 900 und 1000 Zeilen. Das sollte doch kein Problem sein oder?

Vielleicht wisst ihr ja was da passiert, mich frustieren diese Tabellen immer so sehr :wut:

Wird diese Methode von einem Thread aufgerufen, der NICHT der Event-Dispatch-Thread ist?

Die Methode wird nach Clich auf einen Button aufgerufen:

public void actionPerformed(ActionEvent ae) {
//...
else if(ae.getSource()==werteCheck){
			addToTable(baureihenCombo.getSelection());
		}
}

Das ganze läuft als Applet.

OK, dann beim zweiten drüberlesen:

gTableModel.addRow(newRow);
newRow.removeAllElements();

Da müßte man sich jetzt die implementierung genauer ansehen, aber das KÖNNTE ein Problem sein (sollte es IMHO nicht, aber KÖNNTE), probier’ da mal stattdessen

gTableModel.addRow(newRow);
newRow = new Vector();

Es funktioniert einwandfrei. :slight_smile:

Ich kann also quasi nicht einfach einen Vektor mehrmals nutzen um Reihen hinzuzufügen, sondern muss immer für jede Reihe einen neuen erstellen, sehe ich das richtig? Ich hatte vorher angenommen, die Elemente des Vektors werden im TableModel gespeichert und es ist egal was danach mit dem Vektor passiert.

Vielen Dank für deine Hilfe.

Ja. Den Vektor kannst du dann auch ganz lokal, nur in der innersten Schleife deklarieren - damit wird diese „versehentliche Wiederverwendung“ auch gleich verhindert.
EDIT> Also so…

for(int i = 0; i<gUebersetzung.size(); i++){
    Vector newRow = new Vector();
    newRow.add(gTypen.get(typ));
    newRow.add(gGroessen.get(groesse));
    newRow.add(gStufen.get(stufe));
    newRow.add(gUebersetzung.get(i));
   
    gTableModel.addRow(newRow);
    debug ++;
    System.out.println("I OK");
}

<EDIT

Ich hätte nicht angenommen, dass die Elemente aus dem Vektor ins TableModel kopiert werden, aber … habe auch die Möglichkeit in Betracht gezogen. Dass das NICHT so ist, ist … naja, IMHO nicht so schön. Dass NICHT in der JavaDoc-dabeisteht, dass das NICHT so ist, ist nicht nur „nicht so schön“ sondern IMHO schon richtig schlecht. Das ist eine wichtige Information - wie man an diesem Thread sieht :wink: