ArrayList wird immer um zwei Elemente erweitert

nieselfriem

Bekanntes Mitglied
Hallo!
In diesem kleinen Beispiel habe ich eine Tabelle die mit einer Datenbank befüllt werden soll und auf Veränderungen in ein den Zellen reagieren soll. Diese Veränderungen sollen in einer ArrayList gespeichert werden um sie dann später wieder der Datenbank zurück zu führen. Nur wird statt einem die ArrayLIst immer um zwei Elemente erhöht
Java:
import java.awt.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.*;
import java.util.ArrayList;

public class Main extends JFrame implements TableModelListener {

    private JTable table;
    private MyDBTableModel model;
    private JLabel gesamt;
    private JButton button;
    private SqlType sqlt = new SqlType();
    private ArrayList<SqlType> sqllist = new ArrayList<SqlType>();
 

    public Main() {
        super("Tabletest");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = getContentPane();

        model = new MyDBTableModel();
        model.addTableModelListener(this);

        table = new JTable(model);
        table.getModel().addTableModelListener(this);
        table.setPreferredScrollableViewportSize(
                new Dimension(400, 80));
        c.add(new JScrollPane(table));

        button = new JButton("OK");
        button.setEnabled(false);
        c.add(button, BorderLayout.SOUTH);

        pack();
        setVisible(true);
            System.out.println("Arraylistgroesse im Kosntrucktor=" + sqllist.size());//beim start 0
    }//Konstrukor

    public void tableChanged(TableModelEvent e) {
        //gesamt.setText("Tabelle wurde verändnert");
        int row = table.getEditingRow();
        int column = table.getEditingColumn();
        String spaltenname = table.getColumnName(column);
        System.out.println("SelectedRow=" + row + "Selected Column=" + column);
        TableModel model2 = (TableModel) e.getSource();
        String columnName = model2.getColumnName(column);
        Object data = model2.getValueAt(row, column);
        int id = (Integer) model2.getValueAt(row, 0);

        System.out.println("Data" + data);
        System.out.println("Spaltenname=" + spaltenname);
        sqlt.setAttribName(columnName);
        sqlt.setData(data);
        sqlt.setId(id);//muss noch ermittelt werden
        sqllist.add(sqlt);
        System.out.println("Arraylistgroesse=" + sqllist.size());//nach einerZelle = 2
        button.setEnabled(true);
    }//tableChanged

    public static void main(String[] args) {
        // TODO code application logic here
        new Main();
    }
}
Wobei der Datentyp SqlType eine Kalsse ist die wie folgt aussieht:
Java:
package mydbtable;

public class SqlType {
    private String attribName;
    private Object data;
    private int id;

    public SqlType() {

    }

    public void setId(int id) {
        this.id=id;
    }

    public void setData(Object data) {
        this.data=data;
    }

    public void setAttribName(String  attribName) {
        this.attribName=attribName;
    }

    public int getId() {
        return this.id;
    }
    public Object getData() {
        return this.data;
    }

    public String getAttribName() {
        return this.attribName;
    }
}
Wieso wird die Größe der ArrayList immer um zwei statt um eins erhöht?

Gruß niesel
 
Hi
wahrscheinlich wird die Methode 2 mal aufgerufen.
Warum kann ich dir auch nicht sagen,
aber es kann sein, dass 2 Events auflaufen und deshalb 2 Elemente
reinbekommst.
Warum debuggst du nicht ??
 
Code:
System.out.println("Vorher Arraylistgroesse=" + sqllist.size());
sqllist.add(sqlt);
System.out.println("Nachher Arraylistgroesse=" + sqllist.size());
Wenn bei "Nachher" eine andere Zahl rauskommt als die bei "Vorher"+1, sag' bescheid.

Vermutlich wird der Listener einfach zu oft benachrichtigt. Gib' vielleicht mal aus, was das für ein Event ist, der da ankommt...
 
Das event der tabellenänderung scheint tatsächlich zweimal aufgerufen zu werden
denn meine Ausgabe gibt bei eine zellenänderung folgendes aus:
Code:
Arraylistgroesse im Kosntrucktor=0
SelectedRow=2 Selected Column=2
Data neues Datum
Spaltenname=Vorname
Vorher Arraylistgroesse=0
nacher Arraylistgroesse=1
SelectedRow=2 Selected Column=2
Data neues Datum
Spaltenname=Vorname
Vorher Arraylistgroesse=1
nacher Arraylistgroesse=2
;
P.S.: habe die Methode tableChanged nochmal verändert und datbei das model2 heruas genommen. dies war wohl unsinnig. Hat aber keine Wirkung gezeigt:
Java:
 public void tableChanged(TableModelEvent e) {
        //gesamt.setText("Tabelle wurde verändnert");
        int row = table.getEditingRow();
        int column = table.getEditingColumn();
        String spaltenname = table.getColumnName(column);
        System.out.println("SelectedRow=" + row + "Selected Column=" + column);
        //TableModel model2 = (TableModel) e.getSource();
        String columnName = table.getColumnName(column);
        Object data = table.getValueAt(row, column);
        int id = (Integer) table.getValueAt(row, 0);

        System.out.println("Data" + data);
        System.out.println("Spaltenname=" + spaltenname);
        sqlt.setAttribName(columnName);
        sqlt.setData(data);
        sqlt.setId(id);//muss noch ermittelt werden
        System.out.println("Vorher Arraylistgroesse=" + sqllist.size());
        //sqllist.add(sqlt);
        System.out.println("nacher Arraylistgroesse=" + sqllist.size());
        button.setEnabled(true);
    }//tableChanged
Gruß niesel
 
Zuletzt bearbeitet:
Ja, wo der Event das zweite mal herkommt kann man eben nicht nachvollziehen.
Gib ihn mal mit System.out.println("Event: "+e); aus, vielleicht hilft's...
 
Die Ausgabe lautet wie folgt:
Code:
Arraylistgroesse im Kosntrucktor=0
SelectedRow=2Selected Column=2
Data neues Datum
Spaltenname=Vorname
Vorher Arraylistgroesse=0
nacher Arraylistgroesse=1
Count=1
Event: javax.swing.event.TableModelEvent[source=mydbtable.MyDBTableModel@3bb2b8]
SelectedRow=2Selected Column=2
Data neues Datum
Spaltenname=Vorname
Vorher Arraylistgroesse=1
nacher Arraylistgroesse=2
Count=2
Event: javax.swing.event.TableModelEvent[source=mydbtable.MyDBTableModel@3bb2b8]
Wobei das TableModel bei mir wie folgt aussieht:
Java:
import java.awt.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.*;
import java.sql.*;

public class MyDBTableModel extends AbstractTableModel {

    private String[] COLUMN_NAMES = {"ID", "Name", "Vorname"};//Spaltennamen
    private static final Class[] COLUMN_CLASSES = {Integer.class, String.class, String.class};
    private Object[][] data;
    private String query = "SELECT * from mitarbeiter";

    public MyDBTableModel() {
        CollectDatas cl = new CollectDatas();
        ResultSet rs = cl.Abfage(query);
        data = cl.makeDataArray(3, rs);
        System.out.println("------------Tabellenarray----");
        for(int i=0; i<10; i++) {
            for(int j=0; j<3;j++) {
               System.out.println(data[i][j]);
            }
        }
    }

    public Class getColumnClass(int col) {
        return COLUMN_CLASSES[col];
    }

    public int getColumnCount() {
        return COLUMN_CLASSES.length;
    }

    public String getColumnName(int col) {
        return COLUMN_NAMES[col];

    }

    public Object getValueAt(int col, int row) {
         Object _obj = null;
        _obj = data[col][row];
        return _obj;
    }

    public int getRowCount() {
        return data.length;
        
    }

    public boolean isCellEditable(int row, int col) {
        return (col == 1 || col == 2) ? true : false;
    }

    public void setValueAt(Object value, int row, int col) {
        if (value == null) {
            return;
        }
        data[row][col] = value;
        fireTableDataChanged();
    }
}

Gruß niesel
 
OK, das war sicherlich ein dummer Fehler. Jedoch besteht weiter das Problem, dass selbst Doppelclicks als Ereignis gewertet werden. Also man macht ein Doppelclick in die Zelle, die Editierbarkeit ist gegeben es wird jedoch nicht geändert. Trotzdem wird es als Editieren einer Zelle gewertet und die ArrayList gefüllt. Ich hatte angenommen, das
Code:
getEditingRow()
und
Code:
getEditingColumn()
nur ein Ereignis werfen, wenn wirklich etwas verändert worden ist. Kann man das evtl. noch beeinflussen?

Gruß
 
Sobald Du einen Doppelclick auf eine Zelle machst, wird der Editor aktiv. Wenn dieser nun nicht per Escape beendet wird, gilt die Zelle als editiert.
Soll das Verhalten geändert werden (Zelle gilt nur als editiert, wenn der Inhalt vorher zu nachher sich unterscheidet) könnte man das mit einem eigenen CellEditor machen.
Eventuell lässt sich das auch einfacher lösen, aber leider fällt mir da spontan nichts ein...
 
Oh, ich hatte gehofft dass beim toString vom TableModelEvent ein bißchen mehr Info steht. Insbesondere der Typ des events. Du kannst dir von dem Event mal
int getColumn()
int getFirstRow()
int getLastRow()
int getType() ( Returns the type of event - one of: INSERT, UPDATE and DELETE)
ansehen, daraus müßte man eigentlich ableiten können, ob doort wirklich was zu tun ist oder nicht...
 

Zurück
Oben