JTable ResultSet + TableModel

  • hi, arbeit mich gerade in JTAble usw ein.

    Hab jetzt folgendes Problem. Hab ein eigenes Datenmodell welches das Resultset enthält ( Ergebnis der Datenbankabfrage). Funktioniert alles wunderbar, Tabelle wird dargestellt, wenn man editiert, wirds mit updateRow in Datenbank geschrieben etc.. Nun will ich neue Daten per Gui in Datenbank schreiben. PROBLEM: Erst beim neuen starten sind die neuen Daten da, was ja klar ist irgendwie. Frage 1: Weshalb aktualisiert sichdie GUI automatisch, wenn man ein Feld ändert ( hab setValue implementiert), und nicht wenn man eine neue Zeile dem ResultSet hinzufügt ? hab da irgendwie ein Verständnisproblem..

    Frage2: Was macht man in dem Fall, wenn sich die Datenquelle ändert und Daten neu in Gui geschrieben werden sollen ? Wahrscheinlich mit TableModelListener, aber das check ich irgendwie nicht, könnte mir da jemand weiterhelfen, wär echt fein....


    nice weekend ant thx

    Kutz

    In jeder noch so negativen Erfahrung liegt unter den Gefühlen das Wissen für später vergraben.

  • 1. Inwiefern aktualisiert sich die GUI da selbst? Du hast eine Tabelle, in der änderst du was, was genau an der GUI ändert sich dann noch?
    2. Die Datenquelle wird von außerhalb deines Programms geändert? Und du möchtest immer, wenn was aktualisiert wird, die neuen Werte gleich anzeigen? Schöne Lösung fällt mir leider grad keine ein, aber mit TableModelListener kannst du afaik keine SQL(Ist doch mit Abfrage gemeint?)-Datenbanken überwachen sondern nur JTables.

  • HIer mal der Entwurfsquelltext...

    Zwecks GUI selbst aktualisieren meine ich, wenn man Zelle selektiert und ändert, dann wird ja beim TableModel "setValue(...) aufgerufen, mit updateString(..) und updateRow wird die Änderung in die Datenbank geschrieben UND automatisch die GUI aktualisiert mit den neuen Daten... Das selbe hätte ich auch gerne wenn ich eine Zeile per Gui in Datenbank einfüge, was ja klappt, nur wird die GUI Nicht automatisch aktualisiert. Das geht irgendwie mit dem TableModelListener, hab ich zumindest in Literatur gelesen, dass dieser verwendet wird, wenn sich Datenquelle ändert, nur wie is mir nicht klar....


    package grafik12.table;


    import javax.swing.*;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableModel;
    import javax.swing.event.TableModelEvent;

    import java.awt.GridLayout;
    import java.awt.Panel;
    import java.awt.TextField;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;


    //Inhalt einfügen

    public class SQLTableDemo3 extends JFrame {

    private SQLConnect connect;
    private ResultSet rs;
    private JTable x;
    private TextField id;
    private TextField nachname;
    private TextField vorname;
    private TextField title;
    private SQLTableModel3 mod;

    public SQLTableDemo3()
    {
    super ("TestDemo3....");
    try {

    connect = new SQLConnect();

    this.rs = connect.query("Select id AS ID, nachname As NACHNAME, vorname AS VORNAME, title AS TITLE from employees");
    mod = new SQLTableModel3(this.rs);
    this. x = new JTable(mod);
    Panel tab =new Panel();
    tab.add(this.x);
    this.setLayout(new GridLayout(2,1));
    this.getContentPane().add(tab);
    Panel unten = new Panel();
    id = new TextField(15);
    nachname = new TextField(15);
    vorname = new TextField(15);
    title = new TextField(15);
    JButton enter = new JButton("INSERT");
    unten.add(id);
    unten.add(nachname);
    unten.add(vorname);
    unten.add(title);
    unten.add(enter);
    this.getContentPane().add(unten);
    enter.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {

    mod.InsertRow(id.getText(), nachname.getText(), vorname.getText(), title.getText());
    }
    });


    } catch (Exception e) {
    System.out.println("Error...."+ e.getMessage());
    System.exit(1);
    }

    }

    public static void main (String [] args)
    {
    SQLTableDemo3 demo = new SQLTableDemo3();
    demo.pack();
    demo.setVisible(true);
    }

    }

    class SQLTableModel3 extends AbstractTableModel{

    private ResultSet result;
    private ResultSetMetaData metadata;
    private int numrows;
    private int numcols;

    public SQLTableModel3(ResultSet x)
    {
    try {

    this.result = x;
    this.metadata = this.result.getMetaData();
    numcols = this.metadata.getColumnCount();
    this.result.last();
    numrows = this.result.getRow();

    } catch (Exception e) {

    }
    }

    public String getColumnName(int column) {

    try {
    return metadata.getColumnLabel(column+1);
    } catch (SQLException e) { return e.toString(); }
    }

    public void InsertRow(String id, String nachname, String vorname, String title)
    {
    try {
    this.result.moveToInsertRow();
    this.result.updateString("id",id);
    this.result.updateString("nachname",nachname);
    this.result.updateString("vorname",vorname);
    this.result.updateString("title",title);
    this.result.insertRow();
    } catch (Exception e) {

    }
    }


    public int getRowCount() { return this.numrows; }

    public int getColumnCount() { return this.numcols; }

    public Object getValueAt(int row, int col) {

    try {
    result.absolute(row+1); // Go to the specified row
    Object o = result.getObject(col+1); // Get value of the column
    if (o == null) return null;
    else return o.toString(); // Convert it to a string
    } catch (SQLException e) {System.out.println("SLKJLKFJLKJ"); return e.toString(); }

    }
    public boolean isCellEditable(int row, int col)
    { return true; }


    //
    public void setValueAt(Object value, int row, int col) {

    try{
    result.absolute(row+1);
    result.updateString(col+1,value.toString());
    result.updateRow();

    }catch(SQLException sqle){
    System.err.println("Error setting value at row "+row+" column "+col+" with value "+value);
    sqle.printStackTrace();

    }
    catch (Exception e){System.out.println("Error .."+ e.getMessage());}

    }

    public Class getColumnClass(int column) { return String.class; }


    }

    In jeder noch so negativen Erfahrung liegt unter den Gefühlen das Wissen für später vergraben.

  • Bitte verwende das Code-Tag.

    Das Ganze ist ein klassisches Model/View - Problem. In deinem Fall ist das ResultSet das Model und das GUI die View.
    Du solltest dir für das ResultSet und sonstige SQL-Sachen ein eigenes Objekt anlegen, welches diese Sachen verwaltet. In dieser Klasse, nennen wir sie einfach einmal SQLModel, gibt es die Möglichkeit, sich mit einem Listener zu registrieren. Das TableModel registriert sich also beim SQLModel und sobald sich das ResultSet ändert, schickt das SQLModel eine Notifikation weg. Erhält das TableModel dann solch eine Notifikation, sendet es selbst Notifikationen an seine registrierten TableModelListener.
    Dieses Konzept funktioniert einwandfrei und ist eine effiziente und elegante Lösung.
    Wie es dann im Detail bei dir aussieht, ist dir selbst überlassen, aber mit diesem Mechanismus funktioniert es garantiert :)
    Lg.
    java-girl

    There's no better place than 127.0.0.1!

  • ok, jetzt hab ich noch ne frage.

    wenn ich eine Zelle ändere und diese mit updateString + updateRow aktualisiere, sehe ich diese Änderung sofort bei der Table ohne dass ich extra nen Listener implementiere. Mein Problem ist aber, dass ich nur das ResultSet ändern möchte und dass danach gleich in der Tabelle darstellen will, aber OHNE updateRow(). Jedenfalls nimmt mir das Modell diese Änderung einfach nicht an und ich weiß einfach nicht weshalb, aber das müsste doch gehen oder , nur das ResultSet zu ändern.?


    public void setValueAt(Object value, int row, int col) {
    try {
    result.absolute(row+1);
    result.updateString(col+1, value.toString());

    }catch (Exception e){System.out.println("Error...");}

    }


    lg kutz

    In jeder noch so negativen Erfahrung liegt unter den Gefühlen das Wissen für später vergraben.

  • Bitte das Code-Tag verwenden!

    Nur das Result-Set ändern müsste natürlich funktionieren.
    Blöde Frage aber willst du wirklich nur das ResultSet ändern oder gleich etwas in der DB ändern? Weil dann müsste man ja meines Wissens ein Query ausführen, oder täusche ich mich da?

    There's no better place than 127.0.0.1!

  • Naja, mein Problem ist einfach dass mir bei setValue() ohne updateRow() die Änderung einfach verlorengeht im Resultset und ich weiß nicht weshalb. Ich will die Änderung nicht sofort in DB schreiben. Lasse ich updateRow stehen, dann wird alles geschrieben u. die GUI automatisch aktualisiert, obwohl ich ja gar keinen listener habe, kann mir das wer erklären ?

    und zweitens würd ich gern beim einfügen einer Zeile sofort diese Änderung in der GUI zeigen, wird mit Listener funktionieren, habs nicht geschaft (mit fireDataChanged() ...

    Jemand ne Idee ?

    lg kutz

    In jeder noch so negativen Erfahrung liegt unter den Gefühlen das Wissen für später vergraben.

  • anscheinend drück ich mich unklar aus *g.

    mir ist klar dass Resultsets aktualisiert werden können, weil wenn ich dies nicht so initialisiert hätte im Statement, dann hätte ich ja ohnehin eine Fehlermeldeung wenn ichs versuchen möchte...

    na egal, werd mich noch weiter spielen damit u. hoffen dass ich den fehler noch entdecke..

    lg kutz

    In jeder noch so negativen Erfahrung liegt unter den Gefühlen das Wissen für später vergraben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!