Mal wieder die JTable

theliberator2007

Grünschnabel
Hallo,

also ich habe hier ein Problem beim hinzufügen von Zeilen in eine JTable.
Ich hab hier und in anderen Foren schon gesucht und eine Menge Tipps ausprobiert, aber das Problem kann ich immer noch nicht beheben.

Beschreibung des Problems:

Mit folgender Methode, versuche ich die Tabelle mit einem neuen DefaultTableModel upzudaten:

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

Nur zur Info:
ArrayList<Object[]> values = this.eImp.getValuesFromFile(this.currentSheet); holt mir die Werte aus einem ExcelFile (an dieser Methode liegts aber mit sicherheit nicht, die funktioniert 1a).

Beim Debuggen sehe ich, dass model die Daten enthält, aber in der Tabelle wird nichts angezeigt, obendrein wird auch noch der Header ausgeblendet.
Ich hab statt
Code:
DefaultTableModel model = new DefaultTableModel();
auch schon versucht, das TableModel der Tabelle zu benutzen
Code:
DefaultTableModel model = (DefaultTableModel)this.table.getModel();
dann krieg ich allerdings folgende Exception:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0

Ich habe wirklich schon alles versucht:
Für die Version mit neuem TableModel hab ich alle möglichen Methoden ausprobiert (invalidate/validate, repaint usw.) aber es passiert einfach gar nichts
Für die Version mit getModel() hab ich auch den Trick mit invokeLater() etc. versucht aber dass hat mir auch gar nichts geholfen.

Ich bin wirklich für jeden Hinweis dankbar.
 
Zuletzt bearbeitet:
Hey,

versuch es mal hiermit.

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

}


MFG

zEriX
 
Hi,

Ich habe mich selbst schon oft und sehr lange mit der JTable auseinander gesetzt.
Schau mal ob du bei dem DefaultTableModel eine Methode fireTableDateChange() oder so ähnich aufrufen kannst. Ansonsten kannst du auch ein eigenes TableModel erstellen und dort die Methode zum ädern der Tabelleninhalte so überschreiben, dass automatisch ein entsprechendes Event abgefeuert wird

z.b.:
Code:
import javax.swing.table.*;
import java.util.*;

public class MyTableModel extends AbstractTableModel {

  private String strColumnNames[]; //Enthlt die Spaltenberschriften
  private Object objData[][];//Enthlt die Daten der Tabelle

  /* Konstruktor */
  public MyTableModel(Object[][] _newDatas, String[] _newColumnNames){
    this.objData = _newDatas;
    this.strColumnNames = _newColumnNames;
  }

    /**
     * Liefert die Anzahl der Spalten
     */
    public int getColumnCount() {
        return(this.strColumnNames.length);
    }

    /**
     * Liefert die Anzahl der Reihen
     */
    public int getRowCount() {
        return(this.objData.length);
    }

    /**
     * Liefert die Beschriftung der gewnschten Spalte
     */
    public String getColumnName(int col) {
        return(this.strColumnNames[col]);
    }

    /**
     * Liefert das Object der gewnschten Zelle
     */
    public Object getValueAt(int row, int col) {
        return(this.objData[row][col]);
    }

    /**
     * Liefert die Klasse des Objects der gewnschten Zelle
     */
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    /**
     * Fllt die gewnschte Zelle mit einem gewnschten Object
     */
    public void setValueAt(Object value, int row, int col) {
        this.objData[row][col] = value;
        fireTableCellUpdated(row, col);
    }

     
}
 
Zuletzt bearbeitet:
Also ich habe die Methode mit

Code:
model.fireTableDataChanged();

ergänzt.

Das einzige was nach wie vor passiert, ist dass der TableHeader, den ich vorher schon gesetzt hatte, auch nicht mehr angezeigt wird.
Wie kann denn das sein? Ich meine das TableColumnModel oder der Header der Scrollpane werden doch in der Methode übnerhaupt nicht manipuliert.
 
Zuletzt bearbeitet:
Das Problem mit dem Header hatte ich auch. Seit ich aber einen eignen TableHeadRenderer verwende passiert dies nicht mehr

Den hier hatte ich in einem Projekt verwendet:

Code:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.io.*;
import java.util.*;

public class MyTableHeadRenderer extends JList implements TableCellRenderer {

  public MyTableHeadRenderer() {
    setOpaque(true);
    setForeground(MyStyle.getCaptionForeground());
    setBackground(MyStyle.getCaptionBackground());
    setFont(MyStyle.getCellFont());
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    ListCellRenderer renderer = getCellRenderer();
    ((JLabel)renderer).setHorizontalAlignment(JLabel.CENTER);
    setCellRenderer(renderer);
  }

  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    setFont(table.getFont());
    String str = (value == null) ? "" : value.toString();
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector v = new Vector();
    try {
      while ((line = br.readLine()) != null) {
        v.addElement(line);
      }
    } catch (IOException ex) {
      ex.printStackTrace();
    }
    setListData(v);
    return this;
  }
}
 
Also ich benutze schon einen eigenen Renderer.

Code:
DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
MyRenderer renderer = new MyRenderer();

     for(int i=0;i<headerLabels.size();i++) 
     {
     TableColumn column = new TableColumn();
     column.setHeaderValue(headerLabels.get(i));
     column.setPreferredWidth(headerWidths.get(i));
     column.setMinWidth(headerWidths.get(i));
     column.setHeaderRenderer(renderer);
     columnModel.addColumn(column);
}
        
this.table.setColumnModel(columnModel);

Wieso ändert sich das TableColumnModel überhaupt, wenn ich das TableModel aktualisiere?
Wozu sind denn die Daten und die Formatierung getrennt?

Ich verstehe nicht im geringsten wo das Problem liegt.
Ich meine, die Methoden gibts schon, die Daten haben korrekt formatiert, die Schleife passt, die MethodenAufrufe werfen keine Fehler oder Exceptions, eigentlich sollte dass dann doch funktionieren!
 
Zuletzt bearbeitet:
Es kann doch nicht sein, dass sich durchs TableModel der Header ändert.
Wozu sind denn die Daten und die Formatierung getrennt.
Was für ein krankes Konstrukt ist denn diese JTable eigentlich!

Ich weiß was du meinst, ich hab die JTable schon so oft verflucht.

Also ich mein, ich habe nicht nur jeder Spalte einen Renderer hinzugefügt, sonder meinen von oben:

Code:
//Fügt jeder Spalte einen HeadRenderer hinzu
    Enumeration enum = this.jTableCalendar.getColumnModel().getColumns();
    while (enum.hasMoreElements()) {
      ((TableColumn)enum.nextElement()).setHeaderRenderer( new MyTableHeadRenderer());
    }3
 
Also die Daten sind von der Formatierung getrennt. Deswegen gibts ja Renderer und Models. Warum das bei dir jetzt so ist, weiß ich nicht. Dafür müsste ich deinen kompletten Code sehen.

Ich verstehe allerdings nicht warum du immer ein neues Model instanzierst und der Tabelle hinzugfügst, statt immer das gleiche Model zu verwenden.

MFG

zEriX
 
Wenn ich kein neues Model aufrufe, sondern mir das Model von der Tabelle

Code:
 DefaultTableModel model = (DefaultTableModel)this.table.getModel();

hole und dann setModel() aufrufe bekomme ich folgende Fehlermeldung:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0

Das hatte ich allerdings in meinem ersten Post schon geschrieben.

@Matze from HWL:
Ich verstehe, dass könnte das Problem mit dem Header lösen, aber erst will ich mal die Daten in die Tabelle bekommen.
Dann werd ich das aber mal versuchen, danke!
 
Dann muss der Fehler wo anders liegen, denn es ist eine normale Getter-Methode die nicht aus einem Array liest. Deshalb kann der Fehler nicht bei dieser Methode liegen.

Poste mal bitte den kompletten Stacktrace des Fehlers.


Du könntest dir aber auch ein komplett eigenes Model für deine JTable definieren und das am Anfang der Table übergeben.

MFG

zEriX
 

Neue Beiträge

Zurück