# DefaultTableModel aktualisieren



## Dutch_OnE (5. Mai 2008)

Hallo,

ich habe folgende Frage. Ich muss eine Angebotsverwaltung schreiben und benutze dabei eine Methode, die sich die benötigten Daten aus einer ArrayList holt.

Diese Methode liefert mir nun die Daten für die Table. Nach Anlegen des ersten Datensatz wird über einen Listener der Frame mit der Tabelle aufgezogen und die Daten angezeigt.

Wenn ich nun einen 2ten Datensatz hinzufüge, ist die Tabelle ja schon fertig und wird nicht neu erstellt. Wie bekomme ich diese aktualisiert, bzw. wie kann ich ihr sagen, dass ein neuer DAtensatz hinzugekommen ist ?

gruß dutch


----------



## Guest (5. Mai 2008)

Es gibt im TableModel ne Funktion die lautet fireTableDataChanged. 
Damit sagst du der tabelle das sich die Daten geändert haben und das sie sich neu darstellen soll...


----------



## Dutch_OnE (5. Mai 2008)

Wie bindet man dieses am besten ein ? Über nen Listener, Methode ... ?


----------



## L-ectron-X (5. Mai 2008)

Lies dir mal das JTable-Tutorial in der FAQ durch, das sollte die Fragen behandeln.


----------



## Dutch_OnE (5. Mai 2008)

Habe ich gerade versucht, aber da komme ich nicht so richtig weiter.

Wie gesagt ich schreibe aus einer Klasse bestimmte Daten in eine ArrayList und erzeuge danach automatisch eine Tabelle in einem neuen Frame.

Beim ersten Datensatz wird die AL gefüllt, die Tabelle holt sich die Daten und zeigt sie an. Beim nächsten Datensatz ist die Tabelle ja schon erstellt. Ich weiß halt nicht wie ich ihm mitteilen kann, das er einen weiteren Datensatz hat, den er anzeigen soll.
[/code]


----------



## SlaterB (5. Mai 2008)

DefaultTableModel.addRow()


----------



## Dutch_OnE (5. Mai 2008)

ich glaube mir fehlt da einfach noch der Zusammenhang.

Das ist der Frame indem ich die Artikel eingebe:







Wenn ich nun hinzufügen drücke, wird dieser Artikel in eine ArrayList geschrieben. Dann wird ein Vector (mit Daten aus Arraylist und Datenbank) für die folgende Tabelle erstellt, die gleichzeitig in einen neuem Frame geöffnet wird. Die Tabelle wird mit Konstruktor erstellt, aber ich weiß halt nicht was ich tun muss, um der Tabelle mitzuteilen, wenn es einen 2 Datensatz gibt. 







Das ist der Quellcode der Tabelle:

```
public class TabNeuesAngebot extends JFrame {

	private static final long serialVersionUID = -7683083478209677885L;
	static JPanel windows;
	
	public TabNeuesAngebot() throws Exception { 
	
		super("ausgewählte Artikel");
		
		final DefaultTableModel model;

		model = new DefaultTableModel(UtilAngebot.getAlleAngbtPosTmpTab(), UtilAngebot.showAngebotsPosSpalten());

		// Das JTable initialisieren
		final JTable table = new JTable(model);
		windows = new JPanel(new FlowLayout());
		
		Container cp = getContentPane();
		
		windows.add(new JScrollPane(table), BorderLayout.CENTER);

		cp.add(windows);
		setSize(800, 350);
		setVisible(true);
	}
}
```

Und das der vom Vector, den die Tabelle im Konstruktor stehen hat. (Die Beschriftung der Tabellenüberschrift lasse ich mal außen vor.

```
public static Vector getAlleAngbtPosTmpTab() throws Exception {
		
		Vector hilfe1 = new Vector();
		Vector hilfe2 = new Vector();
		
		for (Enumeration<AngebotsPosition> el = hilfe.elements(); el.hasMoreElements();) {
			
			AngebotsPosition angbtPos = el.nextElement();
			int angbtNr = Integer.parseInt(angbtPos.getAngebotsNr());
			int artkNr = Integer.parseInt(angbtPos.getArtikelNr());
			float menge = angbtPos.getMenge();
			int pos = 1;
			float preis = 0f;
			float gesamt = 0f;
			hilfe2.add(pos);
			hilfe2.add(artkNr);
			OracleDB db = OracleDB.getInstance();
			System.out.println(artkNr);
			ResultSet rs1 = db.doQuery("select * from Artikel where ArtikelNr = " +  artkNr);
			while (rs1.next()){
				hilfe2.add(rs1.getString("Bezeichnung"));
				hilfe2.add(rs1.getString("Einheit"));
				preis = (rs1.getFloat("Preis"));
			}
			hilfe2.add(menge);
			preis = Math.round((float) (preis * 100)) / 100f;
			gesamt = menge * preis;
			hilfe2.add(preis);
			hilfe2.add(gesamt);
			pos ++;
			rs1.close(); 
		}
		hilfe1.add(hilfe2);
		return hilfe1;
	}
```


----------



## Dutch_OnE (5. Mai 2008)

hilfe ist die ArrayList


----------



## SlaterB (5. Mai 2008)

> model = new DefaultTableModel(UtilAngebot.getAlleAngbtPosTmpTab(), UtilAngebot.showAngebotsPosSpalten()); 

an der Stelle erstelle bitte kein Model sondern gib den Inhalt der Vectoren aus,
wenn du da zwei Zeilen/ Einträge drin siehst, dann kann man weiterreden,
denke aber dass nur eine drin ist

edit: 
es kann ja gar nur ein Element drin sein, nur hilfe2, alles was du aus der DB liest steht in hilfe2,
so funktioniert eine JTable aber nicht,
für jede Zeile brauchst du einen neuen Vector im Hauptvector hilfe1 (tolle Namen..)


----------



## Dutch_OnE (5. Mai 2008)

So, ich habe mir das nochmal genauer angeschaut. Also ich gebe ja hilfe1 zurück. Für jeden Datensatz erstellt ich ein hilfe2, welches dann zu hilfe1 geadded wird. Daher sollte dieser Vector doch so richtig sein.

Meiner Meinung nach soll die Methode wie folgt funktionieren:

Zunächst erstelle ich 2 Vectoren um einen mehrdimensionalen Vector zu erhalten


```
Vector hilfe1 = new Vector();
Vector hilfe2 = new Vector();
```
 
Dann gehe ich meine ArrayList (hilfe) und hole mir jedes Element	

```
for (Enumeration<AngebotsPosition> el = hilfe.elements(); el.hasMoreElements();) {
			
	AngebotsPosition angbtPos = el.nextElement();
	int angbtNr = Integer.parseInt(angbtPos.getAngebotsNr());
	int artkNr = Integer.parseInt(angbtPos.getArtikelNr());
	float menge = angbtPos.getMenge();
```

Dann hole ich mir zusätzliche Informationen aus der DB und lege die in den Vector hilfe2 rein.
Die Preis Elemente werden dabei gerundet und die Position automatisch hochgezählt. Somit besteht mein kompletter Vector hilfe2 aus "Position, ArtikelNr, Bezeichnung, Einheit, Preis, Gesamtpreis".


```
int pos = 1;
	float preis = 0f;
	float gesamt = 0f;
	hilfe2.add(pos);
	hilfe2.add(artkNr);
	OracleDB db = OracleDB.getInstance();
	ResultSet rs1 = db.doQuery("select * from Artikel where ArtikelNr = " +  artkNr);
	while (rs1.next()){
		hilfe2.add(rs1.getString("Bezeichnung"));
		hilfe2.add(rs1.getString("Einheit"));
		preis = (rs1.getFloat("Preis"));
	}
                hilfe2.add(menge);
	preis = Math.round((float) (preis * 100)) / 100f;
	gesamt = menge * preis;
	hilfe2.add(preis);
	hilfe2.add(gesamt);
	pos ++;
	rs1.close(); 
}
```

Zum Abschluss lege ich hilfe2 in den Vector hilfe1 und sollte somit einen mehrdimensionalen Vector habe, den die Funktion zurückgibt.	

```
hilfe1.add(hilfe2);
	return hilfe1;
	}
```

Nun dachte ich eigentlich das er für das DefaultTableModel eine Methode gibt, die anhand der Daten im Konstruktor, diese nochmal aktualisieren kann.
Vielleicht fehlt mir auch einfach noch das Verständnis, worin der Vorteil eines DefaultTableModel und einer normalen JTable liegt.


----------



## Dutch_OnE (5. Mai 2008)

Jetzt habe ich nochmal etwas weiter getestet.
Der Vector funktioniert richtig. Das Problem ist der Aufruf. Da ich die Methode, die mir den Vector hilfe1 für die Tabelle gibt, nur im Konstruktor meiner DefaultTableModels aufrufe, wird der Vector nur einmal abgerufen und hat daher nur einen Datensatz.

Nun rufe ich diese Methode in einem Listener jedesmal wenn ich einen neuen Artikel hinzufüge per Hand auf und der Vector füllt sich wie er soll. 

Nur wie bekomme ich nun meinen aktuelle Vector an das DefaultTableModel übergeben ?


----------



## SlaterB (5. Mai 2008)

da schaust du dir nun erstmal alle zur Verfügung stehende Operationen an:
http://java.sun.com/javase/6/docs/api/javax/swing/table/DefaultTableModel.html

Tipp: fängt mit set.. an


----------



## Dutch_OnE (5. Mai 2008)

Im Moment habe ich folgenden Zustand erreicht:


```
public class TabNeuesAngebot extends JFrame {

	private static final long serialVersionUID = -7683083478209677885L;
	static JPanel windows;
	
	public TabNeuesAngebot() throws Exception { 
	
		super("ausgewählte Artikel");
		
		DefaultTableModel model = null;
		System.out.println(model);
		
		model = new DefaultTableModel(UtilAngebot.getAlleAngbtPosTmpTab(), UtilAngebot.showAngebotsPosSpalten());
		System.out.println(UtilAngebot.getAlleAngbtPosTmpTab());
		System.out.println(model);
		
		// Das JTable initialisieren
		JTable table = null;
		table = new JTable(model);
		
		windows = new JPanel(new FlowLayout());
		
		Container cp = getContentPane();
		
		windows.add(new JScrollPane(table), BorderLayout.CENTER);

		cp.add(windows);
		setSize(800, 350);
		setVisible(true);

	}
}
```

und das ist mein Ereignis:

null
[[1, 300002, Cola, Liter, 1.0, 0.79, 0.79]]
javax.swing.table.DefaultTableModel@1ebd75b
null
[[1, 300002, Cola, Liter, 1.0, 0.79, 0.79, 2, 300003, Wein, Liter, 2.0, 5.49, 10.98]]
javax.swing.table.DefaultTableModel@7808b9
Programm beendet

Die Tabelle und das Model wird gelöscht, dann kommt der Vector. Auch wenn im Vector beide Datensätze angezeigt werden, sehe ich in meiner Tabelle nur den ersten stehen.

Ich frage mich, warum er nicht den 2ten Satz anzeigt !!!!


----------



## SlaterB (5. Mai 2008)

weil du immer noch nur einen einzigen Vector mit 14 statt 7 Elementen drin hast,
stattdessen brauchst du zwei Untervectoren mit je 7 Einträgen

aus
[[1, 300002, Cola, Liter, 1.0, 0.79, 0.79, 2, 300003, Wein, Liter, 2.0, 5.49, 10.98]] 
muss
[[1, 300002, Cola, Liter, 1.0, 0.79, 0.79], [2, 300003, Wein, Liter, 2.0, 5.49, 10.98]]
werden


----------



## Dutch_OnE (5. Mai 2008)

genau das war es. ich habe den hilfe2 außerhalb des resultset gehabt. nun funktioniert es.


----------



## Dutch_OnE (5. Mai 2008)

Vielen Dank für Eure Hilfe.

GRuß Dutch


----------

