# JTable mit verschiedenen Objekten füllen



## xadoX (4. Mai 2011)

Ist es möglich in einem TableModel verschiedene Objekte zu speichern und bei spätere Selektion auch wieder das richtige Objekt zurückzubekommen?

Im Folgenden speicher ich Objekte der Klasse "Artikel". Möchte aber gerne Objekte der Klassen "eBayArtikel" und "ShopArtikel" speichern. Wie lässt sich das realiseren?


```
public class ArtikelTableModel implements TableModel{
    private ArrayList<Artikel> artikelListe = new ArrayList<Artikel>();
    private ArrayList listeners = new ArrayList();


    /**
     * Fuegt TableModel einen Artikel hinzu
     * @param artikel der Artikel zum hinzufuegen
     */
    public void addArtikel(Artikel artikel){
        int index = artikelListe.size();
        artikelListe.add(artikel);
        TableModelEvent e = new TableModelEvent(this, index, index,
                TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );

        // Listener benachrichtigen
        for( int i = 0, n = listeners.size(); i<n; i++ ){
            ((TableModelListener)listeners.get(i)).tableChanged(e);
        }
    }

    public void removeArtikel(Artikel removingArticle){
        Artikel articleHelp;
        int index = 0;
        if(!artikelListe.isEmpty()){
            for (int i=0; i<artikelListe.size(); i++){
                articleHelp = artikelListe.get(i);
                if(removingArticle.getArtikelID()==articleHelp.getArtikelID()){
                    artikelListe.remove(i);
                    index = i;
                    break;
                }
            }
        }

        // Listener benachrichtigen
        TableModelEvent tme = new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);

        // Das Event verschicken
        for(int i = 0; i<listeners.size(); i++){
            ((TableModelListener)listeners.get(i)).tableChanged(tme);
        }
    }

    /*******************************************************/
    /* Ab hier die Funktionen des Interface implementieren */
    /*******************************************************/

    public int getRowCount() {
        return artikelListe.size();
    }

    public int getColumnCount() {
        return 5;
    }

    public String getColumnName(int columnIndex) {
        switch(columnIndex){
            case 0: return "Artikel-ID";
            case 1: return "Titel";
            case 2: return "Preis";
            case 3: return "Anzahl";
            case 4: return "Angebotstyp";
            default: return null;
        }
    }

    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex){
            case 0: return Integer.class;
            case 1: return String.class;
            case 2: return Double.class;
            case 3: return Integer.class;
            case 4: return Double.class;
            default: return null;
        }
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        Artikel art = artikelListe.get(rowIndex);
        switch(columnIndex){
            case 0: return art.getArtikelID();
            case 1: return art.getArtikelnummer();
            case 2: return art.getTitel();
            case 3: return art.getAnzahl();
            case 4: return art.getPreis();
            default: return null;

        }
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void addTableModelListener(TableModelListener l) {
        listeners.add(l);
    }

    public void removeTableModelListener(TableModelListener l) {
        listeners.remove(l);
    }
```


----------



## xadoX (17. Mai 2011)

Niemand eine Idee?


----------



## SlaterB (17. Mai 2011)

was funktioniert denn nicht, kannst du nicht einen eBayArtikel einfügen?
welche Fehlermeldung gibt es oder anderweitiges Problem?
oder gehts um konzeptionell noch ganz ungeahnte Erweiterungen wie unterschiedliche Anzeige in der Tabelle?


----------



## xadoX (17. Mai 2011)

Das Problem wovor ich steht ist folgendes:

Es gibt ein ArtikelTableModel welches Objekte der Klasse eBayArtikel und ShopArtikel aufnehmen soll.
Woher soll jetzt z.b. die Funktion 

public Object getValueAt(int rowIndex, int columnIndex) 

wissen ob an der Stelle "rowIndex" ein eBayArtikel oder ShopArtikel ist?


----------



## SlaterB (17. Mai 2011)

am besten soll die Methode das überhaupt nicht wissen (wozu? elementare Info, elementar verschwiegen)
ansonsten gibts wie überall in Java die Standard-Mittel:
- Endaufgabe Cast auf Subklasse, 
vorher besser vergewissern, ob es die richtige Klasse ist, sonst ClassCastException, dafür
- Vergleich der Class-Objekte
- instanceof
- Methode der Basisklasse, von Subklasse evtl. überschrieben, gibt den Typ als Enum, String, int, usw., oder boolean zurück, 
public boolean isEbay()


----------



## xadoX (17. Mai 2011)

Manchmal sieht man den Wald vor lauter Bäumen nicht mehr.

Danke für den Gedankenstoß SlaterB. 

Da eBayArtikel und ShopArtikel vom Artikel abgeleitet sind konnte ich einfach eine ArrayList besteht aus Artikel-Objekten erstellen und nutzen.

Allerdings hab ich jetzt ein anderes Problem.
Zu Beginn meiner Gui ist die Tabelle leer.  Die Tabelle befindet sich in einem Scrollpane.
Wenn jetzt während der Arbeit an der Gui ein Nutzer mehr als 6 Artikel erstellt dann passen leider trotzdem nur 6 in die Tabelle. Der Rest wird abgeschnitten und nicht dargestellt.
Ne Ahnung woran das liegen könnte?


----------



## HoaX (17. Mai 2011)

Dein JTable liegt nicht in einer JScrollpane.


----------



## SlaterB (17. Mai 2011)

vielleicht an deinen selbstgebauten TableEvents, schon probiert von AbstractTableModel/ DefaultTableModel zu erben und da die vorgegebenen Methoden zu nutzen?

wenn du eine komplette GUI postest, kann ich da noch reinschauen


----------



## xadoX (17. Mai 2011)

Durch den Gui Builder sieht die Reihenfolge der Initialisierung wie folgt aus:

Beim Start:


```
jTableArtikel = new javax.swing.JTable();
jScrollPane4 = new javax.swing.JScrollPane();

jTableArtikel.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));

jScrollPane4.setViewportView(jTableArtikel);

ArtikelTableModel atm = new ArtikelTableModel();
jTableArtikel.setModel(atm)
```

Ich überschreibe also das vom GuiBuilder erzeugte Model und geb der Tabelle das ArtikelTableModel.


----------



## SlaterB (17. Mai 2011)

ich persönlich kann nicht mehr sagen, zum Ausprobieren bräuchte ich wirklich viel mehr Code, auch die Klasse Artikel z.B.


----------



## xadoX (17. Mai 2011)

Warum die Klasse Artikel?
Die Daten werden ja dargestellt. Nur nicht alle. Scheinbar ist einfach nicht genug Platz in der Tabelle.
Obwohl eigentlich natürlich genug Platz da ist.


----------



## SlaterB (17. Mai 2011)

wie gesagt: ich kann nichts weiter aus dem Kopf sagen, frage nun zum dritten Mal nach dem kompletten Code,
weil das die Voraussetzung zum Testen wäre, muss aber auch nicht sein


----------



## xadoX (17. Mai 2011)

Der Code der Gui hat über 2700 Zeilen. Das will ich Dir nicht antun.

Man kann in der Tabelle sogar mit den Pfeiltasten nach untenscrollen, obwohl man keine weiteren Datensätze sieht. Also die Daten sind da, allerdings werden sie halt nicht ganz gezeichnet.
Siehe folgendes Bild:


----------



## SlaterB (17. Mai 2011)

2700 Zeilen will natürlich niemand sehen, man kann ja auch testweise kürzen..,

weil du bisher solange warten musstest, stelle ich ausnahmsweise ein Programm zusammen,
bei mir allerdings ohne Fehler, daher kann ich weiter nicht hellsehen, was bei dir los ist


```
public class TestGUI
    extends JFrame
{
    public TestGUI()
        throws Exception
    {
        JTable jTableArtikel = new javax.swing.JTable();
        JScrollPane jScrollPane4 = new javax.swing.JScrollPane();

        jTableArtikel.setModel(new javax.swing.table.DefaultTableModel(new Object[][]
            {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}}, new String[]
            {"Title 1", "Title 2", "Title 3", "Title 4"}));

        jScrollPane4.setViewportView(jTableArtikel);

        ArtikelTableModel atm = new ArtikelTableModel();
        jTableArtikel.setModel(atm);

        add(jScrollPane4);


        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 300);
        setVisible(true);

        for (int i = 0; i < 200; i++)
        {
            Thread.sleep(500);
            atm.addArtikel(new Artikel());
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        new TestGUI();
    }
}


class ArtikelTableModel
    implements TableModel
{
    private ArrayList<Artikel> artikelListe = new ArrayList<Artikel>();
    private ArrayList listeners = new ArrayList();


    /**
     * Fuegt TableModel einen Artikel hinzu
     * 
     * @param artikel
     *            der Artikel zum hinzufuegen
     */
    public void addArtikel(Artikel artikel)
    {
        int index = artikelListe.size();
        artikelListe.add(artikel);
        TableModelEvent e = new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);

        // Listener benachrichtigen
        for (int i = 0, n = listeners.size(); i < n; i++)
        {
            ((TableModelListener)listeners.get(i)).tableChanged(e);
        }
    }

    public void removeArtikel(Artikel removingArticle)
    {
        Artikel articleHelp;
        int index = 0;
        if (!artikelListe.isEmpty())
        {
            for (int i = 0; i < artikelListe.size(); i++)
            {
                articleHelp = artikelListe.get(i);
                if (removingArticle.getArtikelID() == articleHelp.getArtikelID())
                {
                    artikelListe.remove(i);
                    index = i;
                    break;
                }
            }
        }

        // Listener benachrichtigen
        TableModelEvent tme = new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);

        // Das Event verschicken
        for (int i = 0; i < listeners.size(); i++)
        {
            ((TableModelListener)listeners.get(i)).tableChanged(tme);
        }
    }

    /*******************************************************/
    /* Ab hier die Funktionen des Interface implementieren */
    /*******************************************************/

    public int getRowCount()
    {
        return artikelListe.size();
    }

    public int getColumnCount()
    {
        return 5;
    }

    public String getColumnName(int columnIndex)
    {
        switch (columnIndex)
        {
            case 0:
                return "Artikel-ID";
            case 1:
                return "Titel";
            case 2:
                return "Preis";
            case 3:
                return "Anzahl";
            case 4:
                return "Angebotstyp";
            default:
                return null;
        }
    }

    public Class<?> getColumnClass(int columnIndex)
    {
        switch (columnIndex)
        {
            case 0:
                return Integer.class;
            case 1:
                return String.class;
            case 2:
                return Double.class;
            case 3:
                return Integer.class;
            case 4:
                return Double.class;
            default:
                return null;
        }
    }

    public boolean isCellEditable(int rowIndex, int columnIndex)
    {
        return false;
    }

    public Object getValueAt(int rowIndex, int columnIndex)
    {
        Artikel art = artikelListe.get(rowIndex);
        switch (columnIndex)
        {
            case 0:
                return art.getArtikelID();
            case 1:
                return art.getArtikelnummer();
            case 2:
                return art.getTitel();
            case 3:
                return art.getAnzahl();
            case 4:
                return art.getPreis();
            default:
                return null;

        }
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex)
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void addTableModelListener(TableModelListener l)
    {
        listeners.add(l);
    }

    public void removeTableModelListener(TableModelListener l)
    {
        listeners.remove(l);
    }
}


class Artikel
{
    private String artikelID;
    private String artikelnummer;
    private String titel;
    private String anzahl;
    private String preis;

    public String getArtikelID()
    {
        return this.artikelID;
    }

    public String getArtikelnummer()
    {
        return this.artikelnummer;
    }

    public String getTitel()
    {
        return this.titel;
    }

    public String getAnzahl()
    {
        return this.anzahl;
    }

    public String getPreis()
    {
        return this.preis;
    }
}
```


----------



## xadoX (17. Mai 2011)

Danke für deine Hilfe.
Ich glaub das Problem gefunden zu haben. Es hängt irgendwie mit preferredSize der Tabelle zusammen.
Hab im GuiBuilder die ScrollPane und die Tabelle gelöscht und nochmal hinzugefügt. Danach klappt es.

Wenn ich dann allerdings auch nur einen Wert bei preferredSize ändere, dann klappts nicht mehr.
Sehr misteriös oder?


----------

