# MySql -> DefaultTabelModel -> JTabel



## StefanKa (20. Dez 2013)

Hallo erstmal,

ich bin zur Zeit in einer Umschulung zum Fachinformatiker Anwendungsentwicklung.
Java haben wir bisher mit Konsolen-Ausgabe gemacht.
Aktuell hab ich jetzt ein Projekt-Auftrag.
Es gibt eine MySQL Datenbank, welche über eine JTabel angezeigt werden soll. Funktioniert soweit auch. Datenbank Verbindung kommt über die Persistence usw...
Dazu gibt es noch eine Eingabemaske um weitere Datensätze zu zufügen, hab ich auch funktioniert auch. Zur Zeit landen die SQL Daten direkt in der JTabel, was ja wenig Sinn gibt, deshalb soll ich jetzt ein DefaultTabelModel bauen, und genau da komm ich nicht weiter, trotz endlos viel lesen im Inet.
Die Struktur sieht so aus:

Project DB-Test
- Source Packages
- - META-INF
- - - persistence.xml
- - daten 
- - - Hersteller.java
- - mappe 
- - - HerstellerTabelModel.java
- - - Manager.java
- - - Start.java

Die Class "HerstellerTabelModel.java ist zur Zeit noch leer, da rein soll ich das DefaultTabelModel bauen, und dann in der Start.java der JTabel zuweisen. Das JFrame und die JTabel wurden nach Vorgabe per Designer erstellt. (In der Manager.java ist der Code für neue Datensätze anlegen drin). Das DefaultTabelModel weise ich der JTabel ja dann mit jTable.setModel(tmodel); zu.

Nur wie erstelle ich dieses DefaultTabelModel, mit Daten, die oben aus der Klasse Hersteller.java kommen. Ich hab mich wie gesagt, durch viele Website,Foren, Tuts gewühlt, aber zur Zeit trette ich einfach auf der Stelle. Entweder schmeissen die jeweils alles in eine Class, oder es liegt als Daten keine Datenbank zu Grunde. Oder es geht nicht über eine Persistence. Somit bitte ich um Hilfe so dass ich über die Tage, an dem Projekt weiter arbeiten kann. Weil wenn das mit den Hersteller klappt, kommen anschliessend noch weitere DatenTabellen hinzu.
Zur Info noch, die HerstellerTabelle ist so aufgebaut. 4 Spalten: hersteller_id, hersteller_name, hersteller_web, hersteller_bemerkung und die Datenbank selbst heisst hardwareverwaltung

Für Tipps, Infos, Codebeispiele oder sonstiges bin ich sehr dankbar,ich nehm jede Hilfe an.

(Wir haben in der umschulung auch nur an 2 Tagen einen Dozenten da, somit ist es auch nicht immer ganz einfach)


----------



## eMmiE (21. Dez 2013)

Muss "Hersteller" eine Java-Datei sein?
Ich mein, die enthält ja nur "Daten", oder?
Wenn das so ist, kannst du das entweder umgehen oder, wenn es eine ".java"-Datei sein muss, aber dann doch nur Daten enthält, mithilfe eines zusätzlichen Classloaders die Datei compilen und dann die Daten auslesen.

Wenn die Daten schon in der Hersteller.java drinstehen und fest definiert sind (iwas = 0, ohne das sie noch geladen werden müssen, dann sehe ich die Sache so, dass du evtl. auch einfach ein Hersteller-Objekt in der DefaultTabelModel - Klasse und dann (das ist jetzt eine Alternative zum Classloader(!)) einfach auf die Daten zugreifst über 
	
	
	
	





```
hersteller.getData()
```

Wenn du bessere Hilfe willst, solltest du vllt. angeben, was das ungefähr für Daten sind, ob die noch geladen werden müssen von der Klasse Hersteller aus, was du darfst und was nicht.

Einfacher machst du dir es auf jeden Fall, wenn du Packages erstellst.

Gruß eMmiE


----------



## turtle (21. Dez 2013)

Hier mal mein kleines Beispiel, was ich oft verwende, um JTable-Dinge zu  demonstrieren. Meistens extende ich aber direkt von AbstractTableModel und nicht von DefaultTableModel.

MenModel hat "nur" einen String als Inhalt.


```
import java.awt.BorderLayout;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class SampleTable extends JPanel {
	private final JTable table;

	public SampleTable() {
		MeinModel model = new MeinModel(4);
		table = new JTable(model);
		add(new JScrollPane(table), BorderLayout.CENTER);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Table");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new SampleTable());
		frame.pack();
		frame.setVisible(true);

	}
}

class MeinModel extends DefaultTableModel {
	public MeinModel(int anzahl) {
		columnIdentifiers = new Vector<String>();
		dataVector = new Vector<String>();
		for (int i = 0; i < anzahl; i++) {
			columnIdentifiers.add("Spalte " + i);
		}

		for (int zeile = 0; zeile < 10; zeile++) {
			Vector<String> oneRow = new Vector<String>();
			for (int i = 0; i < anzahl; i++) {
				int zelle = i + 4 * zeile;
				oneRow.add("" + zelle);
			}
			dataVector.add(oneRow);
		}
	}
}
```


----------



## ARadauer (21. Dez 2013)

also ich würde von einem Default Table model erben, diesem Model würde ich eine Liste von Herstellern geben und dann die entsprechenden Methoden überschreiben... zb so:


```
import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;


public class HerstellerTableModel extends AbstractTableModel {

	private List<Hersteller> data = new ArrayList<Hersteller>();
	private static String[]headings = {"Id", "Name", "Web"};
	
	@Override
	public int getRowCount() {
		return data.size();
	}

	@Override
	public int getColumnCount() {
		return headings.length;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Hersteller hersteller = data.get(rowIndex);
		switch (columnIndex) {
		case 0:
			return hersteller.getId();
		case 1:
			return hersteller.getName();
		case 2:
			return hersteller.getWeb();
		default:
			break;
		}
		return null;
	}

	@Override
	public String getColumnName(int column) {
		return headings[column];
	}

	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		Hersteller hersteller = data.get(rowIndex);
		String value = (String) aValue;
		switch (columnIndex) {
		case 0:
			hersteller.setId(Long.parseLong(value));
			break;
		case 1:
			hersteller.setName(value);
			break;
		case 2:
			hersteller.setWeb(value);
			break;

		default:
			break;
		}
	}
	
	

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return true;
	}

	public void setData(List<Hersteller> herstellerList) {
		data = herstellerList;
		fireTableDataChanged();
		
	}
	
	

}
```


```
public class Hersteller {

	private long id;
	private String name;
	private String web;

	public Hersteller(long id, String name, String web) {
		super();
		this.id = id;
		this.name = name;
		this.web = web;
	}

	public Hersteller() {
		super();
	}

	public long getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getWeb() {
		return web;
	}

	public void setWeb(String web) {
		this.web = web;
	}

}
```


```
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JTable;


public class Test {

	public static void main(String[] args) {
		HerstellerTableModel model = new HerstellerTableModel();
		
		JFrame frame = new JFrame("JTable test");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new JTable(model));
		
		List<Hersteller> herstellerList = new ArrayList<Hersteller>(); //hier zb von db laden
		herstellerList.add(new Hersteller(1l, "Hersteller A", "www.google.at"));
		herstellerList.add(new Hersteller(2l, "Hersteller B", "www.facebook.at"));
		herstellerList.add(new Hersteller(3l, "Hersteller C", "www.twitter.at"));
		
		model.setData(herstellerList);
		
		frame.pack();
		frame.setVisible(true);
	}
}
```

also so mal quick and dirty, da gibts dann noch ein paar frameworks die diese arbeit erleichtern können, aber grundsätzlich kann man low level so mit dem datamodel arbeiten... was ja auch für einfache dinge sehr schnell geht.


----------



## StefanKa (21. Dez 2013)

Da die Frage aufgekommen ist, wie es in der Hersteller.java aussieht, hier mal der Inhalt der besagten Datei. Ob das eine Java sein muss, gute Frage, die wurde automatisch von Netbeans erstellt, als wir die Persistence angelegt hatten. Wie gesagt, das war eigentlich alles soweit Vorgabe vom Dozenten.
Es gibt analog zu der Herteller.java auch noch 7-8 weitere, wie Baustein.java / Schnittstelle.java usw... (wie in der Persistence.xml unten zu sehen ist)
Ich hab mich jetzt immer nur auf Hersteller bezogen, weil ich denk, wenn ich es für Hersteller verstanden habe, krieg ich den Rest dann alleine hin.

Die weiteren Antworten schonmal vielen Dank dafür, muss ich nachher mal in Ruhe anschauen

"Hersteller.java"

```
package daten;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name = "hersteller", catalog = "hardwareverwaltung", schema = "")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Hersteller.findAll", query = "SELECT h FROM Hersteller h"),
    @NamedQuery(name = "Hersteller.findByHerstellerId", query = "SELECT h FROM Hersteller h WHERE h.herstellerId = :herstellerId"),
    @NamedQuery(name = "Hersteller.findByHerstellerName", query = "SELECT h FROM Hersteller h WHERE h.herstellerName = :herstellerName"),
    @NamedQuery(name = "Hersteller.findByHerstellerWeb", query = "SELECT h FROM Hersteller h WHERE h.herstellerWeb = :herstellerWeb")})

public class Hersteller implements Serializable {
    @Transient
    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "hersteller_id", nullable = false)
    private Integer herstellerId;
    @Basic(optional = false)
    @Column(name = "hersteller_name", nullable = false, length = 50)
    private String herstellerName;
    @Basic(optional = false)
    @Column(name = "hersteller_web", nullable = false, length = 150)
    private String herstellerWeb;
    @Basic(optional = false)
    @Lob
    @Column(name = "hersteller_bemerkung", nullable = false, length = 2147483647)
    private String herstellerBemerkung;

    public Hersteller() {
    }

    public Hersteller(Integer herstellerId) {
        this.herstellerId = herstellerId;
    }

    public Hersteller(Integer herstellerId, String herstellerName, String herstellerWeb, String herstellerBemerkung) {
        this.herstellerId = herstellerId;
        this.herstellerName = herstellerName;
        this.herstellerWeb = herstellerWeb;
        this.herstellerBemerkung = herstellerBemerkung;
    }

    public Integer getHerstellerId() {
        return herstellerId;
    }

    public void setHerstellerId(Integer herstellerId) {
        Integer oldHerstellerId = this.herstellerId;
        this.herstellerId = herstellerId;
        changeSupport.firePropertyChange("herstellerId", oldHerstellerId, herstellerId);
    }

    public String getHerstellerName() {
        return herstellerName;
    }

    public void setHerstellerName(String herstellerName) {
        String oldHerstellerName = this.herstellerName;
        this.herstellerName = herstellerName;
        changeSupport.firePropertyChange("herstellerName", oldHerstellerName, herstellerName);
    }

    public String getHerstellerWeb() {
        return herstellerWeb;
    }

    public void setHerstellerWeb(String herstellerWeb) {
        String oldHerstellerWeb = this.herstellerWeb;
        this.herstellerWeb = herstellerWeb;
        changeSupport.firePropertyChange("herstellerWeb", oldHerstellerWeb, herstellerWeb);
    }

    public String getHerstellerBemerkung() {
        return herstellerBemerkung;
    }

    public void setHerstellerBemerkung(String herstellerBemerkung) {
        String oldHerstellerBemerkung = this.herstellerBemerkung;
        this.herstellerBemerkung = herstellerBemerkung;
        changeSupport.firePropertyChange("herstellerBemerkung", oldHerstellerBemerkung, herstellerBemerkung);
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (herstellerId != null ? herstellerId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Hersteller)) {
            return false;
        }
        Hersteller other = (Hersteller) object;
        if ((this.herstellerId == null && other.herstellerId != null) || (this.herstellerId != null && !this.herstellerId.equals(other.herstellerId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "daten.Hersteller[ herstellerId=" + herstellerId + " ]";
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.removePropertyChangeListener(listener);
    }
    
}
```

und der Vollständigkeithalber noch die Persistence.xml dazu

```
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="DB1PU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>daten.Lizenz</class>
    <class>daten.Bausteinschnittstelle</class>
    <class>daten.Softwaretyp</class>
    <class>daten.Hardwaretyp</class>
    <class>daten.Baustein</class>
    <class>daten.Geraet</class>
    <class>daten.Schnittstellen</class>
    <class>daten.Software</class>
    <class>daten.Raum</class>
    <class>daten.Hersteller</class>
    <class>daten.Geraetsoftware</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hardwareverwaltung?zeroDateTimeBehavior=convertToNull"/>
      <property name="javax.persistence.jdbc.password" value="896771"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.user" value="root"/>
    </properties>
  </persistence-unit>
</persistence>
```


----------



## StefanKa (22. Dez 2013)

So hab das mal nach meinem Wissen, alles so zusammen gebaut. Ergebnis ist, dass die  Spaltenüberschriften angezeigt werden, aber keinen Tabelleninhalt.
Im oberen Post hab ich die Persistence.xml  und die Hersteller.java gepostet, hier jetzt noch die HerstellerTableModel.java und die Start.java.
Vielleicht mag mir ja nochmal jemand helfen, wie wo ich noch was falsch habe. Eine Fehlermeldung gibt es soweit nicht. Wie oben schon erwähnt, ist meine erste JTabel mit TabelModel. Weiter noch zur Info der ganze FrameCode wurde mit dem Designer erzeugt. Bin ich zwar eigentlich kein Fan von, aber der Dozent meinte, in Java sei dies angebracht, da der Aufwand zum Ergebnis sich nicht lohnt. Und auch die Struktur soll so erhalten bleiben.

HerstellerTableModel.java

```
package mappe;

import daten.Hersteller;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class HerstellerTableModel extends AbstractTableModel {
    
    private List<Hersteller> data = new ArrayList<Hersteller>();
    private static final String[]headings = {"Id", "Name", "Web", "Bemerkung"};
    
    @Override
    public int getRowCount() {
        return data.size();
    }
 
    @Override
    public int getColumnCount() {
        return headings.length;
    }
 
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Hersteller hersteller = data.get(rowIndex);
        switch (columnIndex) {
        case 0:
            return hersteller.getHerstellerId();
        case 1:
            return hersteller.getHerstellerName();
        case 2:
            return hersteller.getHerstellerWeb();
        case 3:
            return hersteller.getHerstellerBemerkung();
        default:
            break;
        }
        return null;
    }
 
    @Override
    public String getColumnName(int column) {
        return headings[column];
    }
 
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        Hersteller hersteller = data.get(rowIndex);
        String value = (String) aValue;
        switch (columnIndex) {
        case 0:
            hersteller.setHerstellerId(Integer.parseInt(value));
            break;
        case 1:
            hersteller.setHerstellerName(value);
            break;
        case 2:
            hersteller.setHerstellerWeb(value);
            break;
        case 3:
            hersteller.setHerstellerBemerkung(value);
            break;
        default:
            break;
        }
    }
 
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }
 
    public void setData(List<Hersteller> herstellerList) {
        data = herstellerList;
        fireTableDataChanged();
        
    }
 
}
```

und nun die Start.java


```
package mappe;

public class Start extends javax.swing.JFrame {

    Manager Man = new Manager();
    HerstellerTableModel model = new HerstellerTableModel();

    public Start() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        DB1PUEntityManager = java.beans.Beans.isDesignTime() ? null : javax.persistence.Persistence.createEntityManagerFactory("DB1PU").createEntityManager();
        herstellerQuery = java.beans.Beans.isDesignTime() ? null : DB1PUEntityManager.createQuery("SELECT h FROM Hersteller h");
        herstellerList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : herstellerQuery.getResultList();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jPanel2 = new javax.swing.JPanel();
        jTextFieldname = new javax.swing.JTextField();
        jLabelname = new javax.swing.JLabel();
        jLabelweb = new javax.swing.JLabel();
        jTextFieldweb = new javax.swing.JTextField();
        jLabelbemerkung = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jButtonneuHersteller = new javax.swing.JButton();
        jLabelneuHerstellerOk = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable1.setModel((model));
        jScrollPane1.setViewportView(jTable1);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addGap(0, 0, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jTabbedPane1.addTab("Hersteller", jPanel1);

        jLabelname.setText("Name");

        jLabelweb.setText("Web");

        jLabelbemerkung.setText("Bemerkung");

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane2.setViewportView(jTextArea1);

        jButtonneuHersteller.setText("Submit");
        jButtonneuHersteller.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonneuHerstellerActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabelneuHerstellerOk, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabelbemerkung)
                            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabelname)
                                .addComponent(jLabelweb)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 90, Short.MAX_VALUE)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jButtonneuHersteller)
                            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(jTextFieldname, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                                .addComponent(jTextFieldweb))
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addGap(76, 76, 76))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabelname))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabelweb)
                    .addComponent(jTextFieldweb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabelbemerkung)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(26, 26, 26)
                .addComponent(jButtonneuHersteller)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE)
                .addComponent(jLabelneuHerstellerOk, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(31, 31, 31))
        );

        jTabbedPane1.addTab("tab2", jPanel2);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING)
        );

        pack();
    }// </editor-fold>                        

    private void jButtonneuHerstellerActionPerformed(java.awt.event.ActionEvent evt) {                                                     
        // TODO add your handling code here:
        Man.neuerHersteller(jTextFieldname.getText(), jTextFieldweb.getText(), jTextArea1.getText());
        jLabelneuHerstellerOk.setText("Eingetragen");
    }                                                    

    public static void main(String args[]) {

        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Start.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Start.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Start.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Start.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Start().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.persistence.EntityManager DB1PUEntityManager;
    private java.util.List<daten.Hersteller> herstellerList;
    private javax.persistence.Query herstellerQuery;
    private javax.swing.JButton jButtonneuHersteller;
    private javax.swing.JLabel jLabelbemerkung;
    private javax.swing.JLabel jLabelname;
    private javax.swing.JLabel jLabelneuHerstellerOk;
    private javax.swing.JLabel jLabelweb;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextFieldname;
    private javax.swing.JTextField jTextFieldweb;
    // End of variables declaration                   
}
```


----------



## turtle (22. Dez 2013)

Ich habe nicht dein ganzes Programm durchprobiert, aber...

Generell empfehle ich, sich grob an MVC zu halten, sprich eine Trennung von Model (Daten) und der View (Anzeige) bzw. der Control (Steuerung) zu beachten.
In Swing sind eigentlich immer VC zusammen in einer JComponent, also auch bei einer JTable. Also bleibt das Model, was du ja auch ordentlich, wie ich das so sehe, angelegt hast. 
Ich würde alle Datenbankzugriffe aus dem Anzeigeteil rauswerfen, weil es da halt nicht hingehört.

Ich habe daher mal mein kleines Demo für eine JTable angehängt. Darin besteht das Model nur aus einem einzigen String. Und weil as für eine andere Frage im Forum so gewollt wurde, nehme ich ein DefaultTableModel, verwende aber eigenltich auch sonst immer indem ich von AbstractTableModel erbe.


```
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class SampleTable extends JPanel {
	private final JTable table;
	private final MeinModel model;

	public SampleTable() {
		model = new MeinModel(4);
		table = new JTable(model);
		add(new JScrollPane(table), BorderLayout.CENTER);
	}

	public JTable getTable() {
		return table;
	}

	public MeinModel getModel() {
		return model;
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Table");
		frame.setLayout(new BorderLayout());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		final SampleTable sampleTable = new SampleTable();
		frame.add(sampleTable, BorderLayout.CENTER);
		JButton btnSave = new JButton("Save");

		btnSave.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Vector arrayList = sampleTable.getModel().getArrayList();
				System.out.println(arrayList);
			}
		});
		frame.add(btnSave, BorderLayout.NORTH);
		frame.pack();
		frame.setVisible(true);
	}
}

class MeinSampleModel extends DefaultTableModel {
	public MeinSampleModel(int anzahl) {
		columnIdentifiers = new Vector<String>();
		dataVector = new Vector<String>();
		for (int i = 0; i < anzahl; i++) {
			columnIdentifiers.add("Spalte " + i);
		}

		for (int zeile = 0; zeile < 10; zeile++) {
			Vector<String> oneRow = new Vector<String>();
			for (int i = 0; i < anzahl; i++) {
				int zelle = i + 4 * zeile;
				oneRow.add("" + zelle);
			}
			dataVector.add(oneRow);
		}
	}
}
```


----------



## ARadauer (23. Dez 2013)

StefanKa hat gesagt.:


> Ergebnis ist, dass die  Spaltenüberschriften angezeigt werden, aber keinen Tabelleninhalt.



Welche Daten? Wo setzt du die Daten ins model?


----------



## StefanKa (23. Dez 2013)

Na, die Daten aus der MySQL-Database. Ich dachte im DefaultTabelModel. Hab das mehr oder weniger aus dem Vorschlag weiter oben übernommen, und bisschen angepasst. Ich weiss auch selber dass ich von diesem Model noch nicht sehr viel Ahnung habe, deswegen hoffe ich ja, es mit Eurer Hilfe hinzukriegen.
Ich versuch seit Tagen, dass irgendwie zum laufen zu kriegen, dass die JTabel alle Infos aus dem DefaultTabelModel kriegt. So dass ich danach dass in Ruhe analysieren und studieren kann. Bis ich es in und auswendig begriffen habe. Denn der Fertige Code bringt mir ja dann nur auch was, wenn ich ihn auch  verstanden habe.

Hab unten mal zwei Bilder angehängt, wie es aussehen sollte, und wie es aktuell aussieht ohne Daten.
Aktueller Stand des Code ist nach wie vor wie in Post 5 + 6 gepostet. Ich trete nach wie vor fast auf der Stelle. Gut bisschen Zeit hab ich noch, die Umschulung dauert noch 1 1/2 Jahre. Nur ich möchte sehr gerne weiter kommen.

(Der Screen mit den Daten drin, war zur der Zeit, als ich noch die Daten direkt ins JTabel geladen hatte, ohne DefaultTabelModel)

(Nehme auch gerne noch Tipps für Literatur entgegen, unser Dozent verweisst meistens auf die Java Insel)


----------



## ARadauer (23. Dez 2013)

Ja ja... die JTable hohlt sich den Wert jeder Zelle aus dem Table Model. Nur wo setzt du die Werte ins Table Model. Ich mache das in der Klasse Test in Zeile 22

Ich würde mir das mal durchlesen http://www.java-forum.org/bilder-gu...t/4841-jtable-uebersicht-teil-1-teil-8-a.html


----------



## StefanKa (24. Dez 2013)

vielen Dank für die Hilfe bisher,
Ich möchte auch nicht den Eindruck aufkommen lassen, dass ich irgendwelche Hausaufgaben gelöst haben möchte. Aber ich setze mich auch erst seit ca. 2 Monate mit Java auseinander.
Und das ist halt die Taktik von meinem Dozenten, schmeißt einem was angefangenes hin und dann heißt es nun manchmal, auch wenn man davon noch kaum Ahnung hat.
Denn Link, JTabel 1-8, hatte ich mir natürlich auch schon zugemühte geführt. Aber den großen Durchblick für ein TabelModel hatte ich da leider auch noch nicht erlangt.
Wie ich schon geschrieben hatte, sobald ich das lauffähig habe, hoffe ich dass ich dann so ganz langsam durchblick, wie der Ablauf im TabelModel ist.

Soweit dass mal zur Info

Die Class Test im Post 4, hatte ich auch schon nachgebaut, mit der Funktionierts soweit auch. Wenn ich da Beispiel Hersteller ins Array fülle. Nur ich brauch ja die Daten aus der Hersteller.java. Und da die Automatisch generiert worden ist, steht da soviel drin, wovon ich wohl nur die Hälfte brauch.
Wenn ich jetzt bei Deinem Beispiel bleib, denk ich, ich müsste ab Zeile 17 das Array mit den Daten aus der Hersteller.java füllen oder ?
Nur wo bauche ich das in meine HerstellerTabelModel.java ein ? Oder wo mach ich noch was falsch ?

Hoffe noch auf weiteres Verständniss und Hilfe. Vielen Dank


----------



## StefanKa (10. Jan 2014)

So nun geht es weiter, hab den ganzen Code mal was verkleinert, den ganzen automatisch generierten Code entfernt. Es erscheint mir nun alles bisschen logischer, aber funktionieren tut es leider trotzdem noch nicht. Könnt ihr bitte nochmals drüber schauen, und bitte seit so nett, und mir weiterhelfen.

Ich denk das Problem liegt irgendwo mit der herstellerList, die ich versuche in der Manager.java zu generieren. Starten kann ich es ohne Fehler, angezeigt wird mir im Frame aber nur die Tabellenüberschrift, und keine Daten. Also irgendwie kommen die Daten aus der EntityClass nicht rein.

Der  Aufbau ist nachwievor der selbe.


Project DB1
Source Packages
Package META-INF
---- persistence.xml
Package daten
---- Hersteller.java
Package mappe
---- HerstellerTabelModel.java
---- Manager.java
---- Start1.java

HerstellerTabelModel.java

```
package mappe;

import daten.Hersteller;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class HerstellerTabelModel extends AbstractTableModel {

    private List<Hersteller> herstellerList;

    private final String[] columnNames = new String[]{
        "ID", "Name", "Bemerkung", "Web"
    };
    private final Class[] columnClass = new Class[]{
        Integer.class, String.class, String.class, String.class
    };

    public HerstellerTabelModel(List<Hersteller> herstellerList) {
        this.herstellerList = herstellerList;
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return columnClass[columnIndex];
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public int getRowCount() {
        return herstellerList.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Hersteller row = herstellerList.get(rowIndex);
        if (0 == columnIndex) {
            return row.getHerstellerId();
        } else if (1 == columnIndex) {
            return row.getHerstellerName();
        } else if (2 == columnIndex) {
            return row.getHerstellerBemerkung();
        } else if (3 == columnIndex) {
            return row.getHerstellerWeb();
        }
        return null;
    }

}
```

Manager.java

```
package mappe;

import daten.Hersteller;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;


public class Manager {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("DB1PU");
    EntityManager em = emf.createEntityManager();
        
    public List<Hersteller> HerstellerList = new ArrayList<>();
    
    public List alleHersteller(){
       HerstellerList =  em.createQuery("SELECT h FROM Hersteller h").getResultList();
        return HerstellerList;
    }
    
  }
```

Start1.java

```
package mappe;

import daten.Hersteller;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

public class Start1 extends JFrame {

    public Start1() {
    
        List<Hersteller> herstellerList = new ArrayList<Hersteller>();
       
        HerstellerTabelModel model = new HerstellerTabelModel(herstellerList);
        
        JTable table = new JTable(model);
       
        this.add(new JScrollPane(table));

        this.setTitle("Editable Table Example");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Start1();
            }
        });
    }
}
```


----------



## StefanKa (13. Jan 2014)

Darf ich mal leise nachfragen, ob sich doch noch jemand meinem Code annimmt. Ich denk der Code im letzten Post, dürfte doch gar nicht mehr so falsch sein. Vielen Dank schonmal


----------



## Harry Kane (14. Jan 2014)

In deiner Start1 legst du dein TableModel mit einer leeren herstellerList an. Diese leere Liste hat natürlich null Rows, weshalb du nichts siehst.
Wenn du die Zeile

```
List<Hersteller> herstellerList = new ArrayList<Hersteller>();
```
durch diese Zeilen aus deiner Manager-Klasse ersetzt

```
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DB1PU");
EntityManager em = emf.createEntityManager();
List<Hersteller> herstellerList =  em.createQuery("SELECT h FROM Hersteller h").getResultList();
```
Deine Managerklasse wird übrigens in deinem Code nicht weiter verwendet.


----------



## StefanKa (14. Jan 2014)

@Harry Kane

Super funktioniert. Endlich hat mein TabelModel Daten, und meine JTabel zeigt nach Wochen des rumtüfteln und programmieren Daten an, vielen vielen Dank.

Jetzt hab ich was zum arbeiten, was soweit funktioniert.
Denn die drei Zeilen sollten eigentlich in der ManagerKlasse verbleiben nach Vorgabe, und das TabelModel sollte von dort die Daten kriegen. Aber da es jetzt erstmal läuft, kann ich damit weiterarbeiten und dies als Basis nutzen. Heißt eine EingabeMaske basteln, und für das TabelModel soll ich noch ein ActionListener einbauen, der dafür sorgt, dass die JTabel auch automatisch aktualisiert wird, wenn eine Eingabe erfolgt ist.

Nochmal vielen vielen Dank

p.s. in der Managerklasse war schon der Code für die Eingabemaske drin, denn ich aber erstmal auskommentiert hatte, zwecks vereinfachen, des TabelModel-Problem


----------



## StefanKa (16. Jan 2014)

*fireTableDataChanged*

So, nun zeigt ja mein TabelModel(AbstractModel) wunderschön die Daten aus der MySql-Database an.
Jetzt hab ich ein zweites TabbedPan gemacht, mit einer Gui für eine neue Eingabe eines Herstellers, funktioniert auch der wird eingetragen in der Database. Nur die JTabel wird noch nicht aktualisiert. Nachdem ich fast alle Links durchgelesen habe, die um fireTableDataChanged handeln. Nur irgendwo hab ich wohl auch hier was vergessen. Wäre wieder sehr dankbar für Tipps und Lösungen.

In der Start2(früher hieß sie noch Start1) gibts folgende ActionPerformed, die dem jButtonHerstEin zugewiesen ist:
(Die System.outs sind nur für mich da, um Ergebnisse zu prüfen)


```
........
public class Start2 extends javax.swing.JFrame {

    Manager man = new Manager();
    List herstellerList = new ArrayList(man.alleHersteller());
    HerstellerTabelModel model = new HerstellerTabelModel(herstellerList);
.........
private void jButtonHerstEinActionPerformed(java.awt.event.ActionEvent evt) {                                                
        man.neuerHersteller(jTextFieldName.getText(), jTextFieldWeb.getText(), jTextAreaBem.getText());
        jLabelNeuHerstOk.setText("Hersteller wurde eingetragen");
        
        herstellerList = man.alleHersteller();
        System.out.println(herstellerList.size());
            
        model.fireTableDataChanged();
        System.out.println(model.getRowCount());
        
        jTableHerst.repaint();
        System.out.println(jTableHerst.getRowCount());
.........
```

In der Managerclass steht folgendes:

```
package mappe;

import daten.Hersteller;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Manager {

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("DB1PU");
    EntityManager em = emf.createEntityManager();
    Hersteller hersteller = new Hersteller();
    public List<Hersteller> herstellerList = new ArrayList<>();

    public List alleHersteller() {
        herstellerList = em.createQuery("SELECT h FROM Hersteller h").getResultList();
        return herstellerList;
    }

    public Object neuerHersteller(String herstellerName, String herstellerWeb, String herstellerBemerkung) {
        try {
            hersteller.setHerstellerName(herstellerName);
            hersteller.setHerstellerWeb(herstellerWeb);
            hersteller.setHerstellerBemerkung(herstellerBemerkung);

            em.getTransaction().begin();
            em.persist(hersteller);
            em.getTransaction().commit();
            return hersteller;
        } catch (Exception e) {
            em.getTransaction().rollback();
            return -1;
        }
    }
}
```

Das TabelModel sieht nach wievor so aus, wie im Vorletzten Post.

Irgendwie dachte ich, zu der jButtonHerstEinActionPerformed Methode, das müsste reichen, wenn ich die herstellerList mit neuen Daten aus der MySql fülle, dann das fireTableDataChanged anwende und zu guter Letzt, die jTable repainte. Aber irgendwie interessiert das meine JTable nach wie vor nicht. Was hab ich vergessen, oder was läuft falsch ?

p.s. Hoffe der Code ausschnitt von der Start2 reicht. Ansonsten steht da nur das komplette Frame mit den 2 TabbedPanes drin.
p.s.2. Sorry die Doppelpost, aber da ich immer wieder paar Schrittchen weiterkomme, ändert sich der aktuelle Stand immer wieder bisschen richtung Ziel


----------



## StefanKa (16. Jan 2014)

Darf leider nicht editieren :bahnhof:

Bitte vorherigen Post beachten.
Hab jetzt erstmal eine Lösung gefunden, weiss aber nicht wie gut die ist.
Funktioniert in dem ich ein neues TabModel generiere.


```
private void jButtonHerstEinActionPerformed(java.awt.event.ActionEvent evt) {                                                
//      Aufruf des Managers, für die DB Eintragung  
        man.neuerHersteller(jTextFieldName.getText(), jTextFieldWeb.getText(), jTextAreaBem.getText());
//     Bestätigungstext in der Gui
        jLabelNeuHerstOk.setText("Hersteller wurde eingetragen");
        
//      herstellerList mit den neu geänderten Daten aus der DB befüllen (über den Manager)
        herstellerList = man.alleHersteller();
//     Neues TabelModel generieren, mit den neuen Daten
        HerstellerTabelModel modelneu = new HerstellerTabelModel(herstellerList);
//     Neues Model der Tabelbekanntgeben
        jTableHerst.setModel(modelneu);
```


----------



## Harry Kane (17. Jan 2014)

Leider hat dein HerstellerTableModel immer noch eine Referenz zu der alten herstellerListe. Wenn Du den Variablennamen herstellerList einem neuen Objekt zuweist, bekommt das TableModel davon nix mit.
Um die neuen Daten zu sehen, ist es nicht notwendig, ein neues TableModel zu erstellen. Es reicht aus, das alte TableModel nur zu aktualisieren.
Es gibt eine ganze Reihe von Methoden, um dein selbst geschriebenes TableModel mit einer update-Funktion auszustatten. Die naheliegendste ist es, eine Methode zum Setzen der Herstellerliste zu definieren:

```
public class HerstellerTabelModel extends AbstractTableModel {
private List<Hersteller> herstellerList;

    public void setData(List<Hersteller> herstellerList){
        this.herstellerList = herstellerList;
        fireTableDataChanged()
    }
}
```
Das ganze wird aber ziemlich kompliziert, wenn du mehrere TableModels hast, in denen du jeweils unterschiedliche Dinge anzeigen lassen möchtest. Dann musst du mehrere Queries laufen lassen und zwischen der Manager-Klasse und den möglicherweise mehreren TableModel geeignete Listen hin-und herschieben.
Was ich vorziehen würde: mache dein Model etwas "intelligenter". Anstatt es einfach dazu zu verwenden, eine Liste, die von irgendwoher kommt, als Tabelle anzuzeigen, kannst du deinem TableModel eine Referenz auf deine Manager-Klasse übergeben und es von dort die Daten selber anfragen lassen. Dann muss das Model natürlich informiert werden, wenn aktuellere Daten vorliegen. Das ganze würde in etwa so aussehen:

```
public class HerstellerTabelModel extends AbstractTableModel {
private List<Hersteller> herstellerList;
private Manager manager;

    public HerstellerTableModel(Manager manager){
        this.manager = manager;
        herstellerList = manager.alleHersteller();
    }
    public void refresh(){
        herstellerList = manager.alleHersteller();
        fireTableDataChanged()
    }
}
```
und in der actionPerformed:

```
private void jButtonHerstEinActionPerformed(java.awt.event.ActionEvent evt) {
    man.neuerHersteller(jTextFieldName.getText(), jTextFieldWeb.getText(), jTextAreaBem.getText());
    model.refresh();
}
```


----------



## StefanKa (21. Jan 2014)

Und wieder ein Danke an Harry Kane, hab es geschafft. 
Nun läuft das hier angefragte Problem TabelModel mit Daten von MySQL inkl. Aktualisierung wunderbar.
Somit sehe ich meine Frage und den Thread als erledigt an.

Recht herzlichen Dank


----------

