Swing JTable TableModel + RowCount

dior

Bekanntes Mitglied
Hi,

ich habe ein kleines Programm welches eine OracleDB ausliest (select) und das Ergebnis in eine JTable schreibt.
Ich habe dieses TableModel:

Java:
public class FillTableTest extends AbstractTableModel{

 /**
 *
 */
 private static final long serialVersionUID = -912060609250881296L;
 private ResultSet rs;
 public int rowCount;
 private int columnCount;
 private ArrayList data=new ArrayList();
 
 public FillTableTest(ResultSet _rs) throws Exception
 {
 setRS(_rs);
 }

 public void setRS(ResultSet _rs)
 throws Exception
 {
 this.rs=_rs;
 ResultSetMetaData metaData=_rs.getMetaData();
 rowCount=0;
 columnCount=metaData.getColumnCount();
 while(_rs.next()){
 Object[] row=new Object[columnCount];
 for(int j=0;j<columnCount;j++){
 row[j]=_rs.getObject(j+1);
 }
 data.add(row);
 rowCount++;
 }
 }

 public int getColumnCount(){
 return columnCount;
 }

 public int getRowCount(){
 return rowCount;
 }

 public Object getValueAt(int rowIndex, int columnIndex){
 Object[] row=(Object[]) data.get(rowIndex);
 return row[columnIndex];
 }

 public String getColumnName(int columnIndex){
 try{
 ResultSetMetaData metaData=rs.getMetaData();
 return metaData.getColumnName(columnIndex+1);
 }catch(Exception e){
 e.printStackTrace();
 return null;
 }
 }
}


Jetzt möchte ich aber noch zusätzlich als 1. (neue) Spalte eine fortlaufende Numerierung der Zeilen haben (wie in excel z.B.).

Also müsste ich ein Tablemodell wie z.B. dieses:
Java:
class LineNumberTableModel extends DefaultTableModel 
{
  public int getColumnCount() 
  {
    return super.getColumnCount() + 1;
  }
  public Object getValueAt( int row, int col )
  {
    if( col == getColumnCount() )
    {
       return new Integer( row );
    } else 
    {
       return super.getValue( row, col );
  }
}

mit meinem kombinieren damit mir die Zeilen Nummeriert werden und ebenfalls das Ergebnis der SQL Query angezeigt wird.


Kann mir dabei bitte jemand helfen?

Danke im Voraus....
 
bei col==0 musst Du einfach nur die Zeile, also row oder auch row+1 zurückgeben.
bei allen anderen musst Du den Wert aus col-1 zurückgeben.
 
[JAVA=9]
if( col == getColumnCount() )[/code]
Hier musst du nicht auf die Gesamtanzahl an Spalten testen, sondern ob die aktuelle Spalte die erste (also Index 0) ist:
Java:
if( col == 0) return row
Der rest stimmt dann wieder.

Aber ich verstehe nicht ganz, wozu du zwei versch. Modelle brauchst. Hau das, was da in deiner
Code:
LineNumberTableModel
-Klasse steht in deine
Code:
FillTableTest
rein, fertig ist.
 
Zuletzt bearbeitet:
Und wo ist das Problem?

Java:
public class FillTableTest extends AbstractTableModel{
    private ResultSet rs;
    public int rowCount;
    private int columnCount;
    private ArrayList data=new ArrayList();
 
    public FillTableTest(ResultSet _rs) throws Exception {
        setRS(_rs);
    }
 
    public void setRS(ResultSet _rs) throws Exception {
        this.rs=_rs;
        ResultSetMetaData metaData=_rs.getMetaData();
        rowCount=0;
        columnCount=metaData.getColumnCount();
        while(_rs.next()){
            Object[] row=new Object[columnCount];
            for(int j=0;j<columnCount;j++){
                row[j]=_rs.getObject(j+1);
            }
        data.add(row);
        rowCount++;
    }
 
    public int getColumnCount(){
        return columnCount + 1;
    }
 
    public int getRowCount(){
        return rowCount;
    }
 
    public Object getValueAt(int rowIndex, int columnIndex){
        Object[] row=(Object[]) data.get(rowIndex);
        return row[columnIndex];
    }
 
    public String getColumnName(int columnIndex){
        try{
            ResultSetMetaData metaData=rs.getMetaData();
            return metaData.getColumnName(columnIndex+1);
        }catch(Exception e){
           e.printStackTrace();
           return null;
        }
    }

    public Object getValueAt( int row, int col ) {
        if( col == 0) return row;
        Object[] row=(Object[]) data.get(row);
        return row[col];
    }
 }
 
Zuletzt bearbeitet:
hmmm danke für den Code aber so funktioniert das nich....

Java:
 public Object getValueAt
ist doppelt...


Ich verstehe auch nicht ganz wo genau die zusätzliche Spalte eingetragen ist?

(Sorry wenn das so Offensichtlich ist das ich das eigentlich selbst sehen sollte, aber irgendwie sehe ich den Wald vor lauter Bäumen nicht)

-> der 2. Code (LineNumberTableModel) den gibt es bei meinem Programm zur Zeit ja noch nicht... den will ich ja erst "dazu bauen"


Wenn ich es so mache:
Java:
public class FillTableTest extends AbstractTableModel{

 /**
 *
 */
 private static final long serialVersionUID = -912060609250881296L;
 private ResultSet rs;
 public int rowCount;
 private int columnCount;
 private ArrayList data=new ArrayList();
 
 public FillTableTest(ResultSet _rs) throws Exception
 {
 setRS(_rs);
 }

 public void setRS(ResultSet _rs) throws Exception {
 this.rs=_rs;
 ResultSetMetaData metaData=_rs.getMetaData();
 rowCount=0;
 columnCount=metaData.getColumnCount();
 while(_rs.next()){
 Object[] row=new Object[columnCount];
 for(int j=0;j<columnCount;j++){
 row[j]=_rs.getObject(j+1);
 }
 data.add(row);
 rowCount++;
 }
 }

 public int getColumnCount(){
 return columnCount + 1;
 }

 public int getRowCount(){
 return rowCount;
 }

 public Object getValueAt(int rowIndex, int columnIndex){
 //Object[] row=(Object[]) data.get(rowIndex);
 //return row[columnIndex];
     if( columnIndex == 0) return rowIndex;
        Object[] row=(Object[]) data.get(rowIndex);
        return row[columnIndex];

 }

 public String getColumnName(int columnIndex){
 try{
 ResultSetMetaData metaData=rs.getMetaData();
 return metaData.getColumnName(columnIndex+1);
 }catch(Exception e){
 e.printStackTrace();
 return null;
 }
 }

Dann wird mir zwar die 1. Spalte durchnummeriert (ist aber die 1. Spalte der Datenbank die überschieben wird) aber ich brauche eine eigene neue spalte am beginn...

Fehlermeldung:
java.sql.SQLException: Ungültiger Spaltenindex: getValidColumnIndex
at oracle.jdbc.driver.OracleResultSetMetaData.getValidColumnIndex(OracleResultSetMetaData.java:138)
at oracle.jdbc.driver.OracleResultSetMetaData.getColumnName(OracleResultSetMetaData.java:306)
at Stromobjekte.FillTableTest.getColumnName(FillTableTest.java:66)
at javax.swing.JTable.addColumn(JTable.java:2770)
at javax.swing.JTable.createDefaultColumnsFromModel(JTable.java:1264)
at javax.swing.JTable.tableChanged(JTable.java:4374)
at javax.swing.JTable.setModel(JTable.java:3676)
at javax.swing.JTable.<init>(JTable.java:612)
at javax.swing.JTable.<init>(JTable.java:553)



EDIT: ok, ist zwar doppelt sehe aber gerade das das im Grunde das gleiche ist. Also einfach eines bzw. mein original ohne if weglassen.... oder?
 
Zuletzt bearbeitet:
Ups, ja tschuldigung... hab ich wohl beom Kopieren übersehen. Die richtige Methode ist die untere von beiden, also
Java:
public Object getValueAt( int row, int col ) {
    if( col == 0) return row;
    Object[] row=(Object[]) data.get(row);
    return row[col];
}
 
Ja so funktioniert das super.:toll:.. aber es wird noch die 1. Spalte mit der Numerierung überschrieben.
Wie füge ich jetzt vor der (durch die sql Abfrage) generierten Tabelle eine neue Spalte ein in der diese Numerierung steht?
 
Ich habe die RowNumberTable.java in mein Prog eingebau.

Wie muss ich die jetzt in meinen Aufruf einbauen? Ich bekomme immer nur ein graues Feld ohne Tabelle wenn ich das probiere...

hier ist mein Aufrufcode:

Java:
JTable table = new JTable(myModelTest());          
        TableRowFilterSupport.forTable(table).apply(); // Filterfunktion mit Rechtsklick importiert (Bibliothek) com.ezware.....
        table.setAutoCreateRowSorter(true);            // asc/desc Filterung mit linksklick
        JFrame f = new JFrame(Objekt + " - " + "Gesamtanzahl der Zeilen (ohne Filterung)= " + countRows(conn, tableName));
        //f.setSize(1500, 800);
   
        Rectangle maxBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();      // Berechnet die Maximal mögliche Größe der Tabelle bzw. des Frames       
        f.setSize(maxBounds.width, maxBounds.height);                                                          // und setzt diese dann auf maximum damit der ganze Bildschirm gefüllt ist!
        f.add(new JScrollPane(table));
        table.setBackground(Color.WHITE);
        // table.setRowHeight(45);
        //Stromobjekte.AutofitTableColumns.autoResizeTable(table, true, 10, true);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

/*
JScrollPane scrollPane = new JScrollPane(table);
        JTable rowTable = new RowNumberTable(table);
        scrollPane.setRowHeaderView(rowTable);
        scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
            rowTable.getTableHeader());
        scrollPane.add(table);
*/

f.setVisible(true);
 
Und was soll der Code uns sagen?

Wenn man "vorne" eine zusätzliche Spalte zur Nummerierung einfügen will, muss die Methode im TableModel übrigens so lauten:
Java:
public Object getValueAt( int row, int col ) {
    if( col == 0)
        return row;
    Object[] row=(Object[]) data.get(row);
        return row[col-1];
}
 
Die Änderung auf col-1 hat keine Veränderung gebracht... es wird immernoch die erstel Spalte mit der Nummerierung überschrieben und keine neue eingefügt.

Der letzte code war im Bezug auf den Post von André ....

Das wäre noch viel schöner als einfach eine Spalte mit Nummern hinzuzufügen.
Aber wenn ich versuche den Code einzubauen (.java Datei habe ich eingebunden..) wird entweder nur die Numerierung wie in dem Beispiel von André angezeigt oder nur meine Tabelle.

Wie kann ich beide anzeigen lassen... dafür war der Code welcher meine Tabelle aufruft.
 
Wie schaut denn das aktuelle TableModel aus?

Das Beispiel von Andre nutzt den RowHeader der ScrollPane, hier wird einfach die Nummerntabelle in den RowHeader der ScrollPane gesetzt.
 
Danke an Alle und vor allem André!!

Mit dem Aufruf funktioniert es!

Java:
JScrollPane sc = new JScrollPane(table);
        JTable rowTable = new RowNumberTable(table);
        f.add(sc);
        sc.setRowHeaderView(rowTable);


:toll:


D A N K E
 

Zurück
Oben