# jTable tableChanged?



## abc1000 (25. Mrz 2008)

Hallo Leute,

ich komm einfach nciht drauf! Ich versuche einen TableListener hinzuzufügen, der bei einer Änderung der Tabelle reagieren soll und mir die neuen Daten zurückgibt. Hab vieles probiert, aber irgendwie hat nichts geklappt. Kann mir jemand kurz ein Beispiel geben?

Schon mal danke!
Alex


----------



## SlaterB (25. Mrz 2008)

```
public class Test
{
    public static void main(String[] args)
    {
        JTable t = new JTable(5, 5);
        t.getModel().addTableModelListener(new TableModelListener()
            {

                public void tableChanged(TableModelEvent e)
                {
                    System.out.println("changed");
                }
            });

        t.setValueAt("a", 2, 2);
        t.getModel().setValueAt("a", 2, 2);
    }
}
```
am besten nur direkt mit dem Model arbeiten, 
die JTable ist eine Darstellungsform (View), die mit den Daten weniger zu tun haben sollte


----------



## abc1000 (25. Mrz 2008)

Hallo,

danke! Ich arbeite mit einem AbstractTableModel. Wenn ich deinen Code hinzufüge, das Programm starte und in der Tabelle z.B. eine Zelle editiere, gibt mir das Programm nicht "changed" aus. Woran kann das liegen?

Gruß Alex


----------



## SlaterB (25. Mrz 2008)

Code-Ausschnitt aus AbstractTableModel:

```
/**
     *  Returns false.  This is the default implementation for all cells.
     *
     *  @param  rowIndex  the row being queried
     *  @param  columnIndex the column being queried
     *  @return false
     */
    public boolean isCellEditable(int rowIndex, int columnIndex) {
	return false;
    }

    /**
     *  This empty implementation is provided so users don't have to implement
     *  this method if their data model is not editable.
     *
     *  @param  aValue   value to assign to cell
     *  @param  rowIndex   row of cell
     *  @param  columnIndex  column of cell
     */
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    }
```

dagegen DefaultTableModel extends AbstractTableModel :


```
/**
     * Returns true regardless of parameter values.
     *
     * @param   row             the row whose value is to be queried
     * @param   column          the column whose value is to be queried
     * @return                  true
     * @see #setValueAt
     */
    public boolean isCellEditable(int row, int column) {
        return true;
    }


    /**
     * Sets the object value for the cell at <code>column</code> and
     * <code>row</code>.  <code>aValue</code> is the new value.  This method
     * will generate a <code>tableChanged</code> notification.
     *
     * @param   aValue          the new value; this can be null
     * @param   row             the row whose value is to be changed
     * @param   column          the column whose value is to be changed
     * @exception  ArrayIndexOutOfBoundsException  if an invalid row or
     *               column was given
     */
    public void setValueAt(Object aValue, int row, int column) {
        Vector rowVector = (Vector)dataVector.elementAt(row);
        rowVector.setElementAt(aValue, column);
        fireTableCellUpdated(row, column);
    }
```

falls du ein eigenenes Model benutzt, welches von AbstractTableModel erbt, dann musst du ähnliches erarbeiten,
nur mit AbstractTableModel kannst du ja gar keine Daten speichern


----------



## rorton (13. Dez 2010)

Ich habe ein ähnliches Problem aber irgendwie komme ich einfach nicht drauf... Google hat mir auch nicht besonders geholfen:

Ich brauche bitte Hilfe mit folgenden Klassen, da ich nicht genau weiß wo ich was noch implementieren muss..

MVC-Architektur-
3 Klassen:

+AbstractTableModel

+Hauptfenster-Klasse: GUI mit Eingabefelder und Buttons für die Speicherung von neuen Film-Objekten
, JTable und meine erstellte Klasse TableModel extends AbstractTableModel werden dort instanziert!

+MainController-Klasse: - dient eben als Actionlistener für die Button-Events und als Startpunkt

..In meiner Gui hab ich ein Eingabefenster, wo ich alles Eigenschaften eingebe.. mit dem speichern-button wird das Objekt in einer ArrayList gespeichert und soll dann im JTable erscheinen!
Mein Problem ist jetzt, ich weiß nicht wie ich dem AbstractTableModel klarmachen soll den Table neu zu zeichnen, da es ja jetzt einen neuen Datensatz gibt!
Das funktioniert eben noch nicht.. wenn ich das programm neu starte werden bei der ersten erstellung des Tables die daten ganz normal angezeigt, aber nicht wenn das App läuft!

Kann mir jemand einen Denkanstoß geben, ob ich einen Listener brauche und wo ich was in meinen Klassen implementieren muss... Ich brauche nur einen groben Überblick!

Danke Leute!


----------



## SlaterB (13. Dez 2010)

in AbstractTableModel gibts
fireTableDataChanged();

das ist bisschen grob über alles, aber tut es erstmal


----------



## rorton (13. Dez 2010)

Danke für die schnelle Antwort..

Das heißt im Klartext ich brauch nur diese Methode in meiner actionPerformed des Buttons im MainController angeben und der Table zeichnet sich from scratch?

wie implentiere ich die fireTableDataChanged im model aus?


----------



## SlaterB (13. Dez 2010)

from scratch ist übertrieben wenn man es hier genau gibt, noch höher ist gar 
fireStructureChanged();
dann kommt die Tabelle auch mit geänderter Spaltenzahl klar,

ansonsten: ja, du hattest eine Frage gestellt und ich eine Antwort gegeben,
jetzt wo du nachfragst bestätige ich dir dass ich es immer noch für die richtige Anwort zu deiner Frage halte 

wo es genau stehen muss und was sonst noch alles zu bedenken ist ist damit nicht gesagt,
an passender Stelle so dass es zur richtigen Zeit drankommt


----------



## rorton (13. Dez 2010)

ja danke, ist mir klar!

jedoch ist mir nicht ganz klar, wie ich fireTableDataChanged im model implementieren muss, damit sich der table neu zeichnet!

wenn ich die methode nicht selbst implementiere kann ich diese auch nicht aufrufen. Für diese Methode brauche ich aber auch einen Listener oder?


----------



## SlaterB (13. Dez 2010)

selber implementieren wäre relativ schwer, in AbstractTableModel (der vorgegebenen Java-Klasse diesen Namens) gibt es die fertig,
wieder (wie 2008) Quellcode:


```
/** List of listeners */
    protected EventListenerList listenerList = new EventListenerList();

    /**
     * Adds a listener to the list that's notified each time a change
     * to the data model occurs.
     *
     * @param	l		the TableModelListener
     */
    public void addTableModelListener(TableModelListener l) {
	listenerList.add(TableModelListener.class, l);
    }


    /**
     * Notifies all listeners that all cell values in the table's
     * rows may have changed. The number of rows may also have changed
     * and the <code>JTable</code> should redraw the
     * table from scratch. The structure of the table (as in the order of the
     * columns) is assumed to be the same.
     *
     * @see TableModelEvent
     * @see EventListenerList
     * @see javax.swing.JTable#tableChanged(TableModelEvent)
     */
    public void fireTableDataChanged() {
        fireTableChanged(new TableModelEvent(this));
    }
```
usw., wenn dein Model von AbstractTableModel erbt, dann gibt es das alles schon, 
bei table.setModel(model); registiert sich die Tabelle als Listener usw.

edit: da steht tatsächlich 'scratch' bei fireTableDataChanged, gut geraten vorhin


----------



## rorton (13. Dez 2010)

wow, na das nenn ich mal eine erklärung! Danke.. du solltest Java-Unterricht geben, wenn du es nicht bereits tust! 

Thanks, hat voll geholfen und funzt super!:applaus:


----------



## rorton (13. Dez 2010)

Ich hätte noch eine Frage zu ListSelectionEvent!

Pro Zeile in meinem JTable steht ein Objekt meiner Klasse Movie.. (Titel,Actor...), die wie schon erwähnt aus meiner arraylist kommen.

wie stell ich das an, das wenn ich irgendwo in eine Zeile klicke, ich alle Eigenschaften des dort befindlichen Objektes meiner Klasse Movie auslesen kann... zum beispiel in eine Gui mit Textfeldern..?


----------



## SlaterB (14. Dez 2010)

was spricht denn gegen ListSelectionIrgendwas?


----------



## rorton (14. Dez 2010)

vermutlich nichts.. nachdem ich keine ahnung davon habe wie das ding funktioniert hab ich mir etwas hilfe erhofft!


----------



## SlaterB (14. Dez 2010)

'ListSelectionEvent jtable example' kannst du in eine Suchmaschine eintippen, führt z.B. zu
ListSelectionModel, JTable and ListSelectionListener : ListSelectionListenerSwing EventJava Tutorial

da siehst du wie ein Event verarbeitet wird, bisschen testen + loggen mit den Indexen musst du eh,
der Rest ist dann in deinem Programm individuell


----------



## rorton (14. Dez 2010)

Danke, Listener funzt.
Mir ist nur nicht ganz klar, wie ich in meiner valueChanged()-Methode vorgehen muss, damit ich an die Objekte die in meiner ArrayList stecken rankomme..  Die Daten aus der ArrayList werden im AbstractTableModel mit getValueAt in den Table geladen.. nur wie bekomme ich die wieder raus? über den Table oder über das AbtractTableModel?


----------



## SlaterB (14. Dez 2010)

besser über das Model, entweder 'offiziell' getValueAt() abfragen, 
oder du kennst den genauen Typ des Models und kannst dort beliebige andere Methoden verwenden


----------



## rorton (14. Dez 2010)

alles klar, leuchtet mir ein! werd ich heute abend versuchen... danke für die hilfe!

weiß zwar noch nicht genau wie an die methoden meiner arraylist rankomm damit ich datensätze löschen kann! Ich hab z.b in einer zeile alle eigenschaften meiner Movie-Klasse.. mit einem klick lade ich alle diese eigenschaften in eine eigene gui mit textfelder... dort kann man dinge bearbeiten und speichern.. somit bräuchte ich ja die add() und remove() meiner ArrayList!


----------



## SlaterB (14. Dez 2010)

solange du nicht vergisst, fireTableDataChanged() oder ähnliches am Ende aufzurufen, baue von mir aus auch eine get-Methode ein die die Liste an sich liefert


----------

