JTable + Datenbank einträge ändern

cute_hamster

Grünschnabel
Hallo Leute also folgendes Problem :
Ich hab ne JTable mit 3 Spalten Nr.|Name|Geb.Dat ...das Problem ist ich dürfte irgendwo nen Fehler drinnen haben denn wenn ich einen Namen editiere und dann eine andere Zelle anklicke schreibt er as von der vorherigen Zelle hinein...
Außerdem weiß ich das passende SQL Statement nicht um die einträge zu aktualisieren.
Meine setValueAt() - Methode schaut momentan so aus :
public void setValueAt(Object avalue, int row, int column)
{
int i;
DatenDB datdb = new DatenDB();
Daten dat;
for(i=0;i<a_list.size();i++){
dat=(Daten)a_list.get(i);
if(column==1){
dat.name=avalue.toString();
fireTableCellUpdated(row,column);
break;
}
else if(column==2){
dat.gebdat=avalue.toString();
fireTableCellUpdated(row,column);
break;
}

}
}
einige werden sicha lachen weil der fehler in meiner logik liegt aber ich steh momentan echt an und hab am Freitag diese Woche ne Prüfung um in die nächste Klasse zu kommen also bitte bitte helft mir ...
Danke schon mal
 

Anhänge

  • JTable.jpg
    JTable.jpg
    14,3 KB · Aufrufe: 669
Also für dein JTable Problem müsstest du mal den ganzen Code zeigen!
SQL Statement zum ändern:

update KUNDE SET Name='aaaaa',alter='25';
 
public class DatenTableModel extends AbstractTableModel{

public ArrayList<Daten> a_list;
public DatenTableModel()
{
setData();
}

public int getColumnCount() {
return 3;
}
public int getRowCount() {
return a_list.size();
}
public Object getValueAt(int row, int column) {
switch (column)
{
case 0:return a_list.get(row).getNummer();
case 1:return a_list.get(row).getName();
case 2:return a_list.get(row).getGebdat();
default:return null;
}
}
public void setData()
{
DatenDB mydata = new DatenDB();
a_list = new ArrayList<Daten>(mydata.getDaten());
}
public Daten getDataAtRow(int selectedRow)
{
return a_list.get(selectedRow);
}

public void setValueAt(Object avalue, int row, int column)
{
int i;
DatenDB datdb = new DatenDB();
Daten dat;
for(i=0;i<a_list.size();i++){
dat=(Daten)a_list.get(i);
if(column==1){
dat.name=avalue.toString();
fireTableCellUpdated(row,column);
break;
}
else if(column==2){
dat.gebdat=avalue.toString();
fireTableCellUpdated(row,column);
break;
}

}
}

public boolean isCellEditable( int rowIndex, int columnIndex )
{
switch(columnIndex)
{
case 0: return false;
case 1: return true;
case 2: return true;
default: return false;
}
}

public String getColumnName(int column) {

switch (column)
{
case 0: return "Nummer";
case 1: return "Name";
case 2: return "Geb.Datum";
default: return "DONNO";
}
}

Ja und im main ruf ich einfach nur die JTable mit dem model als Parameter auf. Die ganzen fire...()-methoden sind auch drinnen und übernehmen alles aus der super-klasse.

Und zum SQL-Statement: ich will dass er die Daten die in der JTable verändert wurden in der DB ändert...dass es trotzdem update bleibt weiß ich aber zu dem was dazu kommt, hab ich über meinem Kopf ein rießen Fragezeichen
 
Zuletzt bearbeitet:
Also ... das ganze mal kurz Umrissen....
Die Zeile in deiner Tabelle repräsentiert eine Objekt(z.B.:Person)
Es gibt standartmäßig 4 Sachen die du implementieren musst.

1. Insert eines neuen Eintrags/Objektes.
2. Delte eines Eintrags/Objektes.
3. Update eines Eintrags/Objektes.

Dazu muss natürlich noch das Select vorhanden sein um die Daten aus der DB zu lesen.

Wenn du etwas in der Tabelle änderst musst du in deiner getValueAt() (im TabelModel) die daten deine interne Variable / Datenstruktur / dein Objekt speichern... dann musst du dir merken, dass du diese Objekt/ diesen Eintrag geändert hast, und das dazugehörige UpdateStatement auf die DB schicken.

Grundprinzip:

Benutz interne Datenstrukturen für deine Daten ( is sauberer) zum Beispiel Listen oder Arrays. Das TableModel ist nur ein Adapter, um die Daten aus deiner Internen DatenStruktur anzuzeigen. Und um Änderungen in der Anzeige zu übernehemen.

DB----Daten---->Interne Datenstruktur(Liste)-------werden angezeigt mit-----> TabelModel in GUI

Anwender ändert Daten in GUI------Änderungen werden übernommen in------> interne DatenStruktur ----> wird abgegelichen auf die DB

So ungefähr vom Ablauf her.

Ich hoffe der Post hilft dir ein bischen ... wenn du Fragen hast. Einfach posten ... bin noch bis ca 16.00 online !

Gruß Gora
 
ja einbissl gholfen hats schon aber irgendwas stimm trotzdem ned es will einfach ned funktionieren...obwohl ich eh schon die neuen daten in die arraylist speicher irgendwo is der hund drin und ich komm ned drauf

public void setValueAt(Object avalue, int row, int column)
{
int i;
DatenDB datdb = new DatenDB();
Daten dat;
setData();
for(i=0;i<a_list.size();i++){
dat=(Daten)a_list.get(i);
if(dat.getName().equals(avalue)&&dat.getGebdat().equals(avalue))
{
System.out.println("kuck");
}
else
{
a_list.set(i, dat);
fireTableCellUpdated(row,column);
}
}
}

public void fireTableCellUpdated(int row, int column) {
// TODO Auto-generated method stub
super.fireTableCellUpdated(row, column);
DatenDB datdb = new DatenDB();
Daten dat=getDataAtRow(row);
datdb.updateDaten(dat);
setData();
}

public void setData()
{
DatenDB mydata = new DatenDB();
a_list = new ArrayList<Daten>(mydata.getDaten());
}

Habs zwar theoretisch kapiert aber praktisch haut das ned hin...BITTE helft mir hab am Freitag prüfung und sollte das können
 
Zuletzt bearbeitet:
1. Frage .. was willst du mit dem Datenbankobjekt in der setValueAt() ?

Die Funktion public void setValueAt(Object avalue, int row, int column)
des Tablemodels wird immer dann aufgerufen, wenn du eine etwas in deiner Tabelle editierst.
dort musst du also die spiecherlogik implementieren

Wenn zum Beispiel dein Tablemodel als Eigenschaft eine ArrayListe hat würde das ganze so aussehen.

Code:
public void setValueAt(Object avalue, int row, int column)
{

 myDataObjekt help = myList.get(row);
   //wenn es an der Position noch kein Objekt in der liste gibt .. erzeuge ein neues und hänge es an.
   if(help == null){
      help = new myDataObjekt();
      myList.add(help);
}else{
   switch(column){
         
          case 1:help.setName(avalue.toString());
                     break;
          case 2: .... usw....
   }
  }
//den hier nicht vergessen ... weil was geupdatet wurde.
this.fireTabelDataChange();
}

Damit hättest du deine Liste geändert...
Noch einmal zu dem Spiel mit den 3 Listen:

1. Daten aus der DB werden gelesen in ArrayList geschrieben...
2. ArrayList(der aktuelle Stand der Datenbank) wird an das tbm übergeben und dem Anwender angezeigt.
3. Anwender ändert, löscht, fühgt hinzu...
4. Anwender drückt "Speichern" (erst hier darf die Speicherung auf die DB erfolgen.)

Anbei habe ich noch ein paar fragen...
warum erzeugst du in jeder Funktion ein neues DB-Objekt
is das sinnvoll... vielleich gibst du deinen Tabelmodel die Eigentschaft DB-Objekt mit
normalerweise ist das Tablemodel nämlich nur ein Adapter ...
Stelle es dir wie ein Trichter auf einer Flasche vor ... der einfach nur realisiert, wie die Daten in die Tabelle oder der Whisky und die Cola in die Falsche kommt/en ... die Datenbank zugriffe werden eigentlich nicht direkt im Tablemodel realisiert.

ich poste dir hier nochmal ein Beispiel für ein TableModel was ich mal geschrieben habe .... vielleicht kannst du damit was anfangen ... um zu verstehen was da geht muss ich haber noch sagen, dass ich mir ein Objekt geschrieben habe, Model model = new Model();
dieses Model repräsentiert die Daten .. dort sind 4 Listen vorhanden...
Update,Insert,DeleteList und eine Aktuelle Ansichtslist ...

Code:
    /**Feld für das Modelobjekt. */
    protected Model model = null;

    /**
     * Default Konstruktor 
     */
    public FeiertagsTableModel() {
    }

    /** 
     * Konstruktor mit dem DatenModel als Parameter.
     * 
     * @param model
     * @throws Exception Falls das ParameterModel null ist.
     */
    public FeiertagsTableModel(Model model) throws NullPointerException {

        if (model != null) {
            this.model = model;
        } else {
            throw new NullPointerException(
                "Fehler im Datenmodel bei der Feiertagstablemodelerzeugung!");
        }
        this.fireTableDataChanged();
    }

    /**     
     * Methode getRowCount 
     * @return int Anzahl der Zeilen der Tabell
     *         also die Anzahl der Elemente in der FeiertagsListe im Datenmodel
     */
    public int getRowCount() {
        return model.feiertageListe.size();

    }

    /** 
     * Methode getColumnCount
     * @return Konstante 2 weil:
     *      1. Spalte das Datum
     *      2. Splate die Beschreibung 
     */
    public int getColumnCount() {
        return 2;
    }

    /** 
     * Die Funktion getValueAt liest an der übergebenen Position zeile,spalte 
     * den Wert aus und gibt ihn als entsprechendes Objekt zurück.
     *
     * @param      zeile    Position in der Tabelle y
     * @param      spalte   Position in der Tabelle x
     * @return     Object vom Typ {@link DataFeiertag}
     *
     */
    public Object getValueAt(int zeile, int spalte) {
        DataFeiertag datum = new DataFeiertag();
        String sb = new String();
        DataFeiertag date = new DataFeiertag();
        date = (DataFeiertag)model.feiertageListe.get(zeile);

        if ((date.datum == null)) {
            sb = "";
        } else {
            datum = model.feiertageListe.get(zeile);
            sb = CalendarUtils.formatDate(datum.datum);
        }

        if (spalte == 0)
            return sb;
        else
            return datum.beschreibung;
    }

    /**    
     * Methode getColumnName
     * 
     * @param spalte  
     * @return String mit dem Spaltennamen
     */
    @Override
    public String getColumnName(int spalte) {
        if (spalte == 0)
            return "Datum:";

        else
            return "Beschreibung";
    }


    // Methode isCellEditable returns true

    /**     
     * Methode isCellEditable 
     * @param zeile
     * @param spalte
     * @return  true Die komplette Tabelle soll editierbar sein 
     */
    @Override
    public boolean isCellEditable(int zeile, int spalte) {
        return true;
    }

    /**     
     * Die Methode addRow hängt ein Element an die FeiertagsListe und somit an 
     * die Tabelle an. 
     * @param anhang
     */
    public void addRow(DataFeiertag anhang) {
        model.feiertageListe.add(anhang);
        model.anhangListe.add(anhang);
        this.fireTableDataChanged();

    }


    /**
     * Die Methode removeRow löscht die ausgewählte Zeile in der Tabelle bzw. 
     * das zugehörige Element in der FeiertageListe.
     * @param zeile
     */
    public void removeRow(int zeile) {
        model.feiertageListe.remove(zeile);
        this.fireTableDataChanged();
    }

    /**
     *  Die Funktion setValueAt setzt einen Wert in der Tabelle an der Position 
     *  zeile,spalte.
     *  In der ersten Spalte setzt er ein Datum in der zweiten einen String
     *  Des weiteren wir bei der Pflege des Datums überprüft ob das in die 
     *  Tabelle eingegebene Datum zulässig ist,
     *  falls nicht wird der Anwender darauf aufmerksam gemacht.
     *  Des Weiteren wird der aktualisierte Eintrag der UpdateListe mitgegeben,
     *  damit die Änderung beim Aufruf des Speichervorgangs auch in die 
     *  Datenbank übernommen wird.
     *
     *  @param  eintrag  
     *  @param  zeile
     *  @param  spalte
     */
    public void setValueAt(Object eintrag, int zeile, int spalte) {

        GregorianCalendar gc = new GregorianCalendar();
        DataFeiertag datum = model.feiertageListe.get(zeile);

        if (this.getRowCount() > 0) {
            if (spalte == 0) {
                if (eintrag.toString().length() == 10) {
                    gc.get(Calendar.DATE);
                    try {
                        gc.setLenient(false);
                        gc.setTime(CalendarUtils.parseString(
                            eintrag.toString()));
                        datum.datum = gc.getTime();
                        model.updateListe.add(datum);
                    } catch (Exception lenient) {
                        JOptionPane.showMessageDialog(null, 
                                                 "Dieses Datum gibt es nicht!");
                        return;
                    }
                } else
                    JOptionPane.showMessageDialog(null, 
                                    "Unzulässiges Datum "
                                     + "eingegeben!\n Bitte Datum überprüfen!");


            } //ende erstes spalten-if
            if (spalte == 1 && eintrag.toString().length() < 31) {
                datum.beschreibung = eintrag.toString();
            } else {
              
            }
        }

        this.fireTableDataChanged();

    }

}


So jetzt hast du ein bischen was zu tun... (zu lesen und zu verstehen vorallem ... wenn Fragen sind einfach melden...)
 
Danke für die super erklärung ^^
ok hab jetzt dass was du mir geschrieben hast in mein programm übernommen ...trotzdem übernimmt er den namen den ich ändere für alle anderen namen ...
kannst du mir vielleicht nochmal helfen ?

edit:
habs problem gefunden war im sql statement drinnen ...
es wartet aber schon das nächste problem...nummer (id) vergabe beim löschen ? kamma die irgendwie automatisch via sql vergeben ?
 
Zuletzt bearbeitet:
Du meinste bestimmt den Schlüssel...
Naja versuch es mal mit einer Sequenz ... die unique is und wo du im programm
in dein Objekt die ID mit seq.nextVal() schreibst ... irgendwie so war das !
freut mich geholfen zu haben ! ;)

Bei gelegenheit ein PrimKey ändert sich nie! selbst wenn du nen Eintrag löscht... ;)

Gruß

Gora
 
Hallo,

cute_hamster ich nehme an du meintest das sql-Statement zum löschen:

"delete * from Tabellenname where Spalte=blubb"
"DELETE * from Geburtstagstabelle WHERE Nummer=8"
 
Naja also wie man löscht weiß ich meine Frage war ob die Nummer wenn sie auch ein primary key is gelöscht wird oda Null gesetzt wird...

Also momentan wird die nummer via ArrayList size() vergeben...wenn ich jetzt aber ein element in der Table lösch stimmt das halt nicht mehr...jetzt hab ich überlegt wie ich das lösen könnte...entweder ich setzte nur name und datum auf Null und frag beim nächsten hinzufügen ab wo der name Null is und schreibs darein
oder
ich lösche die ganze zeile und verteil die nummer für alle neu ?

nächste Frage : woher weiß ich welche Zeile gerade markiert ist...damit ich diese via einem löschen button -löschen kann ...

wenn es noch lösungsvorschläge gibt bitte posten...ansonsten einfach sagen was einfacher zum realisieren is mit wenig arbeit ...

danke schon mal
 
Zuletzt bearbeitet:
Zurück