# JTable zeigt die alte Daten wieder



## ottens (8. Mai 2012)

Hallo leute,

ich habe eine Frage und bitte euch um Hilfe und zwar mit MausKlick kann ich ein bestimmets 
File wählen und seine gefilterte Daten in Liste bzw Array laden und dann in ein 
DefaultTableModel-Object schieben und das Model-Object zu JTable einfügen, die Tabelle 
zeigt mir alle Daten richtig und kann mit drucken auf Knopf die weitere existirte Daten 
sehen (Daten werden in JTable Schubweise angezeigt).
das Problem liegt daran, wenn ich danach ein zweites File wähle dann werden seine Daten 
richtig angezeigt, wenn ich aber auf die Tabelle klicke werden die Daten vom ersten File 
(die Letzte Daten, die man angezeigt hat) sichtbar und die neu geladene daten verschwinden.
ich habe die Listen, Arrays, JTable und das Model-Object auf NULL gesetzt  hilft 
alles nicht woran kann es liegen ???

kann mir bitte jemand helfen  :bahnhof:


----------



## Camino (8. Mai 2012)

Na ja, sieht wohl so aus, als wären die alten Daten immer noch in deinem Model drin. Aber ohne den relevanten Code wird dir hier niemand weiterhelfen können. Am besten zeigst du mal, wie und wo die Daten ins Model kommen.


----------



## ottens (8. Mai 2012)

hier ist der Code 

wenn die erste Tabelle z.B. 10 Zeilen hat und die neu gezeichnete Tabelle 7 zeilen hat dann beim klicken 
auf die Tabelle werden die alte Zeilen auch sichtbar manchmal die Schrift des Inhalts der Felder wird verzerrt .

public class MyJTableDemo extends AbstractTableModel implements AdjustmentListener,TableModelListener{
	ArrayList<String> spaltenNamen = new ArrayList<String>();
	Object[] title = new String[4];
	String[] zeilen = new String[spaltenNamen.size()];;
	Object[][] data = new String[zeilen.length][title.length];
	DefaultTableModel model;// = DefaultTableModel(data, title);
	JPanel tablePanel = new JPanel();
	ArrayList<String> werteListe = new ArrayList<String>();
	JScrollPane scrollTable;

	JTable table = new JTable(model);

	int position = 0;

	public JPanel getTablePanel(ArrayList<String> spaltenNamen,ArrayList<String> werteListe, int position) {
		this.spaltenNamen = spaltenNamen;
		this.werteListe = werteListe;
		this.position = 0;

		String temp = new String();
		int zaehler = 0;
		int ab = position * spaltenNamen.size();
		zeilen = new String[spaltenNamen.size()];
		title = new String[] { "SpaltenName", "Wert", "Typ",
				"Spalte dient als Ersatz" };

		for (int i = 0; i < spaltenNamen.size(); i++) {
			temp = spaltenNamen.get(i).toString();
			zeilen_ = temp;
			temp = new String();
		}
        data=null;
		data = new String[zeilen.length][title.length];

		for (int i = 0; i < zeilen.length; i++) {
			for (int j = 0; j < title.length - 1; j++) {
				if (j == 0) {
					data[j] = zeilen[zaehler];
					zaehler++;
				} else if (j == 1) {
					data[j] = filtern(werteListe.get(ab));
					data[2] = typBestimmen(data[j]);
					ab++;
				}
			}
		}

		// Das JTable initialisieren
		model = new DefaultTableModel(data, title);
		table = new JTable(model);
		table.setModel(model);
		model.fireTableDataChanged();
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table.getColumn(title[0]).setPreferredWidth(150);
		table.getColumn(title[1]).setPreferredWidth(130);
		table.getColumn(title[2]).setPreferredWidth(130);
		table.getColumn(title[3]).setPreferredWidth(130);
		tablePanel = new JPanel();
		tablePanel.setPreferredSize(new Dimension(320, 230));
		scrollTable = new JScrollPane(table);
		scrollTable.setPreferredSize(new Dimension(320, 230));
		scrollTable.getVerticalScrollBar().setValue(
				scrollTable.getVerticalScrollBar().getMaximum());
		scrollTable.getHorizontalScrollBar().setValueIsAdjusting(true);
		scrollTable.setAutoscrolls(true);
		scrollTable.getVerticalScrollBar().addAdjustmentListener(this);
		tablePanel.add(scrollTable, BorderLayout.CENTER);

		return tablePanel;
	}
	public void updateTable(int position) {
		int ab = position * spaltenNamen.size();
		scrollTable.setAutoscrolls(true);
		table.getColumn(title[0]).setPreferredWidth(150);
		table.getColumn(title[1]).setPreferredWidth(120);
		table.getColumn(title[2]).setPreferredWidth(130);
		table.getColumn(title[3]).setPreferredWidth(130);
		for (int i = 0; i < zeilen.length; i++) {
			for (int j = 0; j < title.length - 1; j++) {

				if (j == 1) {
					data[j] = null;
					data[2] = null;
					data[j] = filtern(werteListe.get(ab));
					data[2] = typBestimmen(data[j]);
					model.setValueAt(data[j], i, j);
					fireTableCellUpdated(i, j);
					model.setValueAt(data[2], i, 2);
					fireTableCellUpdated(i, 2);
					System.out.println(data[j]);
					ab++;
					table.repaint();
				}
			}
		}
	}

danke im vorraus_


----------



## Camino (8. Mai 2012)

Bitte den Java-Code auch in die JAVA-Tags (siehe roten Text beim schreiben von Beiträgen) setzen.


----------



## Camino (8. Mai 2012)

Was soll das denn ergeben:

```
// Das JTable initialisieren
model = new DefaultTableModel(data, title);
table = new JTable(model);
table.setModel(model);
model.fireTableDataChanged();
```

Du erstellst ein Model, dann ein JTable, dem du im Konstruktor dieses Model übergibst, dann setzt du *nochmal* das Model beim JTable mit 
	
	
	
	





```
table.setModel(model);
```
. Das zweite mal setzen des Models ist unnötig, das fireTableChanged() wohl auch.


----------



## ottens (8. Mai 2012)

entschuldige bitte !!


```
public class MyJTableDemo extends AbstractTableModel implements AdjustmentListener,TableModelListener{
ArrayList<String> spaltenNamen = new ArrayList<String>();
Object[] title = new String[4];
String[] zeilen = new String[spaltenNamen.size()];;
Object[][] data = new String[zeilen.length][title.length];
DefaultTableModel model;// = DefaultTableModel(data, title);
JPanel tablePanel = new JPanel();
ArrayList<String> werteListe = new ArrayList<String>();
JScrollPane scrollTable;

JTable table = new JTable(model);

int position = 0;

public JPanel getTablePanel(ArrayList<String> spaltenNamen,ArrayList<String> werteListe, int position) {
this.spaltenNamen = spaltenNamen;
this.werteListe = werteListe;
this.position = 0;

String temp = new String();
int zaehler = 0;
int ab = position * spaltenNamen.size();
zeilen = new String[spaltenNamen.size()];
title = new String[] { "SpaltenName", "Wert", "Typ",
"Spalte dient als Ersatz" };

for (int i = 0; i < spaltenNamen.size(); i++) {
temp = spaltenNamen.get(i).toString();
zeilen[i] = temp;
temp = new String();
}
data=null;
data = new String[zeilen.length][title.length];

for (int i = 0; i < zeilen.length; i++) {
for (int j = 0; j < title.length - 1; j++) {
if (j == 0) {
data[i][j] = zeilen[zaehler];
zaehler++;
} else if (j == 1) {
data[i][j] = filtern(werteListe.get(ab));
data[i][2] = typBestimmen(data[i][j]);
ab++;
}
}
}

// Das JTable initialisieren
model = new DefaultTableModel(data, title);
table = new JTable(model);
table.setModel(model);
model.fireTableDataChanged();
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumn(title[0]).setPreferredWidth(150);
table.getColumn(title[1]).setPreferredWidth(130);
table.getColumn(title[2]).setPreferredWidth(130);
table.getColumn(title[3]).setPreferredWidth(130);
tablePanel = new JPanel();
tablePanel.setPreferredSize(new Dimension(320, 230));
scrollTable = new JScrollPane(table);
scrollTable.setPreferredSize(new Dimension(320, 230));
scrollTable.getVerticalScrollBar().setValue(
scrollTable.getVerticalScrollBar().getMaximum());
scrollTable.getHorizontalScrollBar().setValueIsAdjusting(true);
scrollTable.setAutoscrolls(true);
scrollTable.getVerticalScrollBar().addAdjustmentListener(this);
tablePanel.add(scrollTable, BorderLayout.CENTER);

return tablePanel;
}
public void updateTable(int position) {
int ab = position * spaltenNamen.size();
scrollTable.setAutoscrolls(true);
table.getColumn(title[0]).setPreferredWidth(150);
table.getColumn(title[1]).setPreferredWidth(120);
table.getColumn(title[2]).setPreferredWidth(130);
table.getColumn(title[3]).setPreferredWidth(130);
for (int i = 0; i < zeilen.length; i++) {
for (int j = 0; j < title.length - 1; j++) {

if (j == 1) {
data[i][j] = null;
data[i][2] = null;
data[i][j] = filtern(werteListe.get(ab));
data[i][2] = typBestimmen(data[i][j]);
model.setValueAt(data[i][j], i, j);
fireTableCellUpdated(i, j);
model.setValueAt(data[i][2], i, 2);
fireTableCellUpdated(i, 2);
System.out.println(data[i][j]);
ab++;
table.repaint();
}
}
}
}
```

danke im vorraus


----------



## ottens (8. Mai 2012)

Hi,
danke für die schnelle reaktion 

ja ich habe viel mit dem Code probiert und geändert daher kann es sein, dass paar Zeilen keinen Sinn haben.

Grüße

Ottens


----------



## Camino (8. Mai 2012)

Um das Ganze mal ein bisschen übersichtlicher zu machen, würde ich View (GUI, JTable) und Model (TableModel) mal in verschiedenen Klasssen trennen. Auf den ersten Blick sehe ich jetzt nicht, wo die neuen Daten ins Model gebracht werden.


----------



## Camino (8. Mai 2012)

Wie unterscheiden sich denn die Daten aus den unterschiedlichen Files? Haben diese Daten die gleiche Struktur, also kann die gleiche Struktur der Tabelle genommen werden, und es ändern sich nur die Daten darin? Oder ist die Struktur (Spalten, Typen) der Tabelle danach völlig anders?


----------



## ottens (8. Mai 2012)

Hi,

also die Tabelle soll so aussehen 


SpaltenName    | Wert    |Typ der Spalte   |Spalte dient als Ersatz

spalte_1         | 123y    |   String 

spalte_2         |123        | Integer

spalte_3         | YES        |boolean 

usw 

die ganze Daten werden von der werteListe in die Reihung data[][]  kopiert und dort werden in Model transportuert durch 

```
model.setValueAt(data[i][j], i, j);
```
 
in Zeile 49 steht 
	
	
	
	





```
model = new DefaultTableModel(data, title);
```

wie soll ich alles in Klassen trennen etwas deutlicher wäre gnaz lieb 

danke


----------



## bERt0r (8. Mai 2012)

Also entweder DefaultTableModel oder AbstractTable model, beides geht wohl kaum.
Eine Funktion wie updateTable brauchst du nicht, du willst doch nur was dazuadden.

```
import java.awt.BorderLayout;


public class TableTestDemo extends JFrame
{
	
	private JPanel contentPane;
	private JTable table;
	private JFileChooser fileChooser=new JFileChooser();
	private DefaultTableModel model=new DefaultTableModel(new String[] {"Dateiname","Größe"},0);
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				public void run()
				{
					try
					{
						TableTestDemo frame = new TableTestDemo();
						frame.setVisible(true);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			});
	}
	
	/**
	 * Create the frame.
	 */
	public TableTestDemo()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JScrollPane scrollPane = new JScrollPane();
		contentPane.add(scrollPane, BorderLayout.CENTER);
		
		table = new JTable(model);
		scrollPane.setViewportView(table);
		
		JButton btnAddFile = new JButton("Add File");
		btnAddFile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) 
			{
				int ret=fileChooser.showOpenDialog(TableTestDemo.this);
				if(ret==JFileChooser.APPROVE_OPTION)
				{
					File f=fileChooser.getSelectedFile();
					model.addRow(new String[]{f.getName(),String.valueOf(f.length())});
				}
			}
		});
		contentPane.add(btnAddFile, BorderLayout.SOUTH);
	}
	
}
```


----------



## ottens (8. Mai 2012)

Hi,

die Files haben die selbe Struktur z.B wenn das Zeicen '<' kommt, dann soll dahinter einen Namen der Spalte stehen ich filtere die Daten und trenne ich sie pro Zeile mit dem '*'  Zeichen daher rufe ich die Funktion 
	
	
	
	





```
data[i][j] = filtern(werteListe.get(ab));
```
 auf (Zeile 41). 

danke .


----------



## Camino (8. Mai 2012)

ottens hat gesagt.:


> wie soll ich alles in Klassen trennen etwas deutlicher wäre gnaz lieb
> 
> danke



Mit welcher IDE/Editor arbeitest du? Wird dir bei dieser Klasse kein Fehler angezeigt? Du hast oben in der Klasse ein 
	
	
	
	





```
extends AbstractTableModel
```
 drinstehen, d.h. du müsstest auf jeden Fall die Methoden getRowCount(), getColumnCount() und getValueAt(int row, int column) bei dir in dieser Klasse stehen haben.

Mit in Klassen trennen meine ich, dass du eine Klasse hast, in der die Ansicht/View (also die JTable) drin ist, und eine andere Klasse mit dem Model hast.

Es gibt hier im Forum auch ein gutes Tutorial zu JTable:
http://www.java-forum.org/bilder-gui-damit-zusammenhaengt/4841-jtable-ubersicht-teil-1-teil-8-a.html


----------



## ottens (8. Mai 2012)

danke bERt0r,

beim klicken auf ein File soll die erste 7 bzw 10 Zeilen in der Reihung [][] data angezeigt werden 
wenn ich aber auf Knopf vorwärts klicke dann sollen die nächsten 7 bzw 10 Zeilen angezeigt werden
usw ich möchte dann die neue Daten in die Tabelle schieben und  die alte Daten überschreiben.


ich habe 
	
	
	
	





```
DefaultTableModel
```
 benutzt habe selber Model-Klasse erstellt 
das selbe Effekt die alte Daten werden immer noch angezeigt wenn ich auf die Tabelle klicke,
wenn die neue Daten sichtbar sind.

habe den Satz "Also entweder DefaultTableModel oder AbstractTable model, beides geht wohl kaum."

nicht richtig verstanden 

danke


----------



## ottens (8. Mai 2012)

danke Camino,

ich benutze Eclipse Helios.

die drei Funktionen habe ich schom implementiert und sind schon in der Klasse und sie leifern die 
geeignete Werte.  

Tutorial habe oft gelesen von SUN auch. 

die Trennung der Klseen ist bei mir so 

eine HauptKlase für die VIEW eine zweite für Parsen und die dritte für die Tabelle, was ich Teil davon
gesendet habe.

danke

Ottens


----------



## Camino (8. Mai 2012)

ottens hat gesagt.:


> habe den Satz "Also entweder DefaultTableModel oder AbstractTable model, beides geht wohl kaum."
> 
> nicht richtig verstanden
> 
> danke



Das TableModel hat die Daten, die in einer JTable angezeigt werden. Du hast davon 2 unterschiedliche: das DefaulTableModel und das AbstractTableModel. Du musst dich für eins entscheiden.

Und mit den verschiedenen Klassen: Du erstellst ein TableModel (eine eigene Klasse, die von AbstractTableModel abgeleitet ist) und übergibst dieses Model dem Konstruktor der JTable. Das TableModel ist dann für die Daten zuständig, d.h. wenn sich bei den Daten was ändert, machst du das über das TableModel und dieses informiert dann die JTable bzw. aktualisiert dann die angezeigten Daten in der Tabelle.


----------



## ottens (8. Mai 2012)

super Camino danke,

 also soll ich 
	
	
	
	





```
extends AbstractTableModel
```
 löschen ?

danke


----------



## ottens (8. Mai 2012)

ich habe gelöscht hilft leider nicht,

ich habe probiert mit einem Test ich kann mit GridLayout(zeilen, spalten) eine Tabelle von
JLabels erstellen, die das selbe anzeigt wie JTable und mit JButton die Werte der JLabels ändern.

aber wenn weitere Vorschläge möchte gerne wissen warum verhält sich JTable so komisch ?

Gruss

Ottens


----------



## Camino (8. Mai 2012)

ottens hat gesagt.:


> möchte gerne wissen warum verhält sich JTable so komisch ?



JTable verhält sich nicht komisch, sondern ist halt ein komplexes Thema. Schau dir mal den Link zum JTable-Tutorial an, den ich weiter oben gepostet habe. Dort stehen die verschiedenen Möglichkeiten, wie du Daten in die Tabelle bekommst.


----------



## ottens (8. Mai 2012)

Hallo wieder,

hängt es vielleicht mit DoubleBuffering  ??

weil die Schrift verzerrt wird ?

grüße

Ottens


----------



## Camino (8. Mai 2012)

Vielleicht eher mit dem Aufbau und der Aktualisierung deiner grafischen Oberfläche. Versuch doch einfach mal Schritt für Schritt eine JTable und ein TableModel zu erstellen, dies dann erst mit festen Werten und dann dynamisch zu füllen, und dann nach und nach weitere Funktionen einzubauen. So lernst du das Phänomen JTable besser kennen und kannst es einfach erweitern. Später wirst du dann sehen, wie einfach das eigentlich alles ist.


----------



## ottens (9. Mai 2012)

Hi,

für die leute, die vielleicht in Zukunft das selbe Problem haben, die Tabelle mit den alten Daten wird auf JPanel wieder im Hintergrung angezeigt obwohl die neue Tabelle mit neuen Daten geladen ist, die 
Lösung habe ich gefunden, man soll den Mutter-Container leeren, in dem man die Methode -  

```
MutterContainer.removeAll();
```
 aufruft, dann erscheint die alte Tabelle nicht mehr.

Grüße

Ottens


----------



## ottens (9. Mai 2012)

Camino hat gesagt.:


> Vielleicht eher mit dem Aufbau und der Aktualisierung deiner grafischen Oberfläche. Versuch doch einfach mal Schritt für Schritt eine JTable und ein TableModel zu erstellen, dies dann erst mit festen Werten und dann dynamisch zu füllen, und dann nach und nach weitere Funktionen einzubauen. So lernst du das Phänomen JTable besser kennen und kannst es einfach erweitern. Später wirst du dann sehen, wie einfach das eigentlich alles ist.



Hi Camino,

danke für die Hilfe finde bist super vielen Dank.

Gruß,

Ottens


----------



## Camino (9. Mai 2012)

ottens hat gesagt.:


> Hi,
> 
> für die leute, die vielleicht in Zukunft das selbe Problem haben, die Tabelle mit den alten Daten wird auf JPanel wieder im Hintergrung angezeigt obwohl die neue Tabelle mit neuen Daten geladen ist, die
> Lösung habe ich gefunden, man soll den Mutter-Container leeren, in dem man die Methode -
> ...



Normalerweise hast du 1 JTable, die in deinem Container (JPanel) dargestellt wird. Wenn sich am Inhalt (Daten) der Tabelle was ändert, änderst du nur das TableModel und nicht die Tabelle. Das TableModel informiert und aktualisiert dann die JTable. Du brauchst also normalerweise nicht die Tabelle entfernen und neu erstellen.


----------

