Mal wieder die JTable

Die Exception wird so weit ich weiß dadurch hervorgerufen, dass Swing nicht thread-sicher ist. Deshalb hatte ich ja schon versucht die Methode mit einen SwingUtilities.invokeLater()-Block zu umgeben, allerdings hat dies dann merkwürdige Probleme mit der Sichtbarkeit der verwendeten Variablen hervorgerufen, also hab ich den Block wieder entfernt.Dazu gibts glaub ich in diesem Forum auch schon Threads.

Trotzdem hier mal der StackTrace:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:432)
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:622)
at javax.swing.JTable.getValueAt(JTable.java:1852)
at javax.swing.JTable.prepareRenderer(JTable.java:3902)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:1985)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1887)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1810)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
at javax.swing.JComponent.paintComponent(JComponent.java:742)
at javax.swing.JComponent.paint(JComponent.java:1005)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JViewport.paint(JViewport.java:728)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4963)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4916)
at javax.swing.JComponent._paintImmediately(JComponent.java:4859)
at javax.swing.JComponent.paintImmediately(JComponent.java:4666)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:114)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)


Das ein eigenes Model das Problem löst, glaube ich nicht, denn ich bekomme ja die Daten problemlos ins Model, nur krieg ich es nicht hin, die Tabelle mit dem neuen Model anzuzeigen. Warum sollte das bei einem eigenen Model anders sein?
 
Zuletzt bearbeitet:
hmm, jetzt mal ohne die Fehler angeschaut zu haben, es handelt sich um eine ArrayIndexOutOfBoundEXCeption - also muss es irgendwo ein zu kleines Array geben. Wie hast du die Tabelle den Initialisiert? Da das defaultTableModel intern ein Array oder Vector je nach Einstellung benutzen kann.
Ich könnte mir vorstellen dass du vieleicht die Tabelle leer initialisiert hast. Also legt Java ein TableModel mit einem Array der länge 0 an und jetzt versuchst du ein dieses Array deine Daten zu bekommen.

Postet bitte mal wie du die JTable initialisiert hast
 
Hast du schon mal kontrolliert, ob die for-Schleife überhaupt ausgeführt wird?

Meine Vermutung ist im Moment, dass hier
Code:
ArrayList<Object[]> values = this.eImp.getValuesFromFile(this.currentSheet);
eine leere ArrayList zurückgegeben wird.

MFG

zEriX
 
Also die Liste enthält definitv 3 Object-Arrays mit Daten.

Ich habe wie gesagt schon so ziemlich alles versucht was mir einfällt, habe die Methode auch step-by-step debugged und überprüft ob alle Daten da sind und im richtigen Format vorliegen.

Hat vielleicht irgendwer schon eine ähnliche Methode wie meine addRows implementiert und würde mir den Code zur Verfügung stellen? Das wär super, vielleicht könnte ich dann diesen Code anpassen.

Sonst wird mir wohl nichts anderes übrigbleiben, als die ganze addRows-Sache mal in einem eigenen Programm auszutesten bzw. nochmal alles neu zu schreiben.
 
Versuch es mal bitte mit diesem Model

Java:
import java.util.ArrayList;

import javax.swing.table.AbstractTableModel;


@SuppressWarnings("serial")
public class TableModelExample extends AbstractTableModel{
	
	private ArrayList<Object[]> data = null;

	public int getColumnCount() {
		if(data != null && data.size() > 0)
			return data.get(0).length;
		return 0;
	}

	public int getRowCount() {
		if(data != null)
			return data.size();
		return 0;
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		if(data != null){
			Object[] o = data.get(rowIndex);
			return o[columnIndex];
		}
		return null;
	}

	public void setData(ArrayList<Object[]> data) {
		this.data = data;
	}

}

Die addRows sollte dann so aussehen
Code:
public void addRows()
{   
        ArrayList<Object[]> values = this.eImp.getValuesFromFile(this.currentSheet); 
        TableModelExample model = (TableModelExample) table.getModel();
        model.setData(values);
        model.fireTableDataChanged();

}


Das TableModel setzt du nur am Anfang bei initialisieren der Table.

MFG

zEriX
 
Also, jetzt hab ich schon mal geschafft die Daten in die Tabelle zu bekommen:

Code:
public void addRows()
{   
        ArrayList<Object[]> values = this.eImp.getValuesFromFile(this.currentSheet);
        DefaultTableModel dtm = (DefaultTableModel)table.getModel();
        dtm.setColumnCount(table.getColumnModel().getColumnCount());
        for(int i=0;i<values.size();i++)
        {   
            dtm.addRow(values.get(i));           
        }
        table.setModel(dtm); 
}

Ich habe mir einfach den ColumnCount vom ColumnTableModel geholt und setze dann den ColumnCount vom TableModel auf denselben Wert-->Daten sind in Tabelle
Aber wieso, checkt das die addRow-Methode nicht selbst, bzw. schaut ob das TableColumnModel einen RowCount besitzt?

Offensichtlich gehen die Informationen des TableColumnModels verloren, wenn man das TableModel aktualisiert, denn der Header verschwindet ebenfalls. Ist das ein Bug oder gibt es einen Grund dafür?
 
Zuletzt bearbeitet:
Also ich habe jetzt mal beide Models von der vorherigen Page kombiniert und meine Tabelle dann mit diesem Model ausgestattet.
Bis auf ein neues merkwürdiges Problem, funktioniert alles so wie vorgesehen, d.h. der Header bleibt erhalten und Daten werden hinzugefügt.

Das Problem, dass jetzt aufgetaucht ist äußert sich folgendermaßen:

Ich habe in meinem TableModel die folgende set-Methode benutzt um die Daten reinzuschreiben:

Code:
public void setData(ArrayList<Object[]> newData) {
   this.data = newData;
   fireTableDataChanged();          
}

Leider werden die Daten in der Tabelle nicht korrekt angezeigt.
Stattdessen wird in jeder Spalte einer Zeile der gleiche Wert angezeigt und zwar der der ersten Spalte.
data enthält aber die Daten von newData, es liegt also irgendwie an der Darstellung der Tabelle oder benutze ich da vielleicht mit fireTableDataChanged() eine falsche Methode?
 
Ich habe die beiden Models kombiniert, damit ich den Header auch im TableModel speichern kann!

Code:
/*
 * MyTableModel.java
 *
 * Created on 7. September 2007, 11:38
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package GUI;

import java.util.ArrayList;       
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author schmidfl
 */

@SuppressWarnings("serial")

public class MyTableModel extends AbstractTableModel {

  private String columnNames[]; //Enthaelt die Spaltenberschriften
  private ArrayList<Object[]> data = null;//Enthaelt die Daten der Tabelle

  /* Konstruktor */
  public MyTableModel(ArrayList<Object[]> _newData, String[] _newColumnNames){
    this.data = _newData;
    this.columnNames = _newColumnNames;
  }

    /**
     * Liefert die Anzahl der Spalten
     */
    public int getColumnCount() {
	if(data != null && data.size() > 0)
		return this.data.get(0).length;
	return 0;
    }

    /**
     * Liefert die Anzahl der Zeilen
     */
    public int getRowCount() {
	if(data != null)
		return data.size();
	return 0;
    }

    /**
     * Liefert die Beschriftung der gewuenschten Spalte
     */
    public String getColumnName(int col) {
        return(this.columnNames[col]);
    }
    
    public void setColumnNames(String[] newColumnNames) {
        if(this.columnNames.length==newColumnNames.length)
            this.columnNames = newColumnNames;
    }


    /**
     * Liefert die Klasse des Objects der gewuenschten Zelle
     */
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    
     /**
     * Liefert das Object der gewuenschten Zelle
     */
    public Object getValueAt(int rowIndex, int columnIndex) {
	if(data != null){
		Object[] o = data.get(rowIndex);
		return o[columnIndex];
	}
	return null;
    }

    /**
     * Fuellt die gewuenschte Zelle mit einem gewuenschten Object
     */
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        this.data.get(rowIndex)[columnIndex] = value;
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    /**
     * Fuellt die komplette Tabelle mit Werten
     */
    public void setData(ArrayList<Object[]> newData) {
        this.data = newData;
        fireTableDataChanged();          
    }     
}

Initialisieren tu ich die Tabelle übrigens mit
Code:
table.setModel(new ArrayList<Object>(), new String[] {});
nur der Vollständigkeit halber
 
Zurück