# Dateneingabe JTable



## MadBlue (5. Feb 2012)

Hallo zusammen,

ich arbeite derzeit an einem BI Projekt und habe mich mit der Dateneingabe total verzettelt. Seit zwei Wochen programmiere ich an einer JTable mit eigenem Renderer und eigenerem Cell Editor herum und langsam habe ich das gefühlt das mich das nicht ans Ziel bringt. Das Projekt ist für mich und mein Studium wichtig... daher wäre ich für Hilfe wirklich dankbar!

ein paar Eckpunkte zu dem Projekt
UA. ist es nötig größere Datenmengen zu erfassen. Das soll über ein GUI ablaufen.
Als Basis für dient eine Excel Datei. (Vereinfacht sieht das so aus: die Excel datei hat eine spalte mit Eingabepunkten (zB. Umsatz, Gewin usw.) davon etwa 1200 Stück... die Eingabe soll aber über eine GUI laufen... hier ist Java vorgegeben...)
Ich habe das Programm schon soweit das es aus den 1200 Eingabefeldern kleine mundgerechte Stückchen rausnimmt und daraus drei Vectoren baut mit denen man auch wirklich schon arbeiten kann... das raus lesen und rein speichern an die richtige stelle funktioniert schon problemlos)



Mein Problem ist die GUI
Wie gesagt ich habe pro "Menü" drei Vectoren
Vector 1: Stellt eine Liste von Strings zu Verfügung die das Eingabefeld betiteln
Vector 2: Spiegelt die eingegebenen Daten einer Spalte wieder... (also Strings oder Doubles... leere Felder sind automatisch " " oder 0.0)
Vector 3: Gibt wieder was für ein Eingabetyp verwendet werden soll (also ob ein Textfeld verwendet werden soll, ob die Eingabe über eine Combobox laufen soll usw.)

Die Vector 1, 2 und 3 sind gleich lang, die Gesamtlänge ist aber nicht fix... ein Menü kann also mal 10 und mal 15 Eingaben erfordern...

Mir erschien es geschickt das als JTable zu machen.
-Ich habe also einen eigenes AbstractTableModel gebaut welches aus den zwei Daten-Vectoren ein passendes TableModel macht
-Ich habe einen TableCellRenderer geschrieben welcher dafür sorgt das die Zellen das richtige Format haben (Label, Checlbox etc.)
-ich habe dann noch einen AbstractCellEditor geschrieben welcher ebenfalls die richtigen Componenten verwendet und die richtigen werte returned...

Es funktioniert sogar mittlerweile soweit das alles richtig ausschaut... Die Zellen haben das richtige Format, die richtigen werte stehen darin, die richtigen Optionen in der ComboBox werden angezeigt etc.

Die Werte werden jedoch nicht in die JTable übernommen...
Wenn ich eine Option aus einer ComboBox auswähle springt sie danach zurück zur Ausgangsoption, beim Text das selbe... selbst wenn die die Klasse "public Object getCellEditorValue()" manuell einen String returnen lasse statt den currentValue kommt dieser nicht in der Tabelle an...

Ich habe in den letzten Tagen elendig viel gegooglet und gelesen... ich komme meinen Millimeter mehr voran... Swing und Co sind absolutes Neuland für mich und hier verliere ich ziemlich den Boden unter den Füßen.

Habe ich mich mit der JTable total verrannt? Gibt es andere Möglichkeiten ein Menü zu bauen welches die Eingabefelder dynamisch erstellt?
Oder gibt es typische Kleinigkeiten welche ich bei der JTable vergessen haben könnte?


Ich häng hier mal meinen Quellcode an, befürchte aber, so zerpflückt wie der durch die ganze rumprobieren ist, wird der etwas kryptisch sein...

TableModel

```
package src;

import java.util.Vector;

import javax.swing.table.AbstractTableModel;

public class MenuTableBuilder extends AbstractTableModel {
	
	int zaehler1;
	int zaehler2;
	//spalte 1, nicht beschreibbar
	Vector row1Data;
	//spalte 2, entspricht den bereits eingetragenen Daten, soll editierbar sein
	Vector row2Data;
	//Pflichtfelder, irrelevant, nocht nicht implementiert
	Vector rowPflicht;
	//gibt das Format an (Textfeld, Combobox, etc.)
	Vector rowArt;
	//evntl. Optionen... zB. bei der combobox)
	Vector rowOption;


	
	public boolean isCellEditable(int row, int col)
	{
		if(col == 1){
		return true;
		}else
		{return false;}
	}
	
	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return zaehler2;
	}
	

	@Override
	public int getRowCount() {
		// TODO Auto-generated method stub
		return zaehler1;
	}

	@Override
	public Object getValueAt(int row, int col) {
		// TODO Auto-generated method stub
		
		
		if(col==1){
			try {
			if ((Double) row2Data.get(row) == 0)
			{
				return "";
			}
			else {
				return row2Data.get(row);
				}
			}catch (Exception e)
			{
				return row2Data.get(row);
			}
			
					
			
		} else {
			
			
			
			return row1Data.get(row);
		}
		
	}
	
	
	
	//GETTER UND SETTER


	public int getZaehler1() {
		return zaehler1;
	}


	public void setZaehler1(int zaehler1) {
		this.zaehler1 = zaehler1;
	}


	public int getZaehler2() {
		return zaehler2;
	}


	public void setZaehler2(int zaehler2) {
		this.zaehler2 = zaehler2;
	}


	public Vector getRow1Data() {
		return row1Data;
	}


	public void setRow1Data(Vector row1Data) {
		this.row1Data = row1Data;
	}


	public Vector getRow2Data() {
		return row2Data;
	}


	public void setRow2Data(Vector row2Data) {
		this.row2Data = row2Data;
	}


	public Vector getRowPflicht() {
		return rowPflicht;
	}


	public void setRowPflicht(Vector rowPflicht) {
		this.rowPflicht = rowPflicht;
	}


	public Vector getRowArt() {
		return rowArt;
	}


	public void setRowArt(Vector rowArt) {
		this.rowArt = rowArt;
	}


	public Vector getRowOption() {
		return rowOption;
	}


	public void setRowOption(Vector rowOption) {
		this.rowOption = rowOption;
	}
	

}
```




Der Cell Renderer

```
package src;

import java.awt.Color;
import java.awt.Component;
import java.util.Vector;
import java.util.StringTokenizer;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

import org.w3c.dom.events.EventException;

public class MenuTableRenderer extends JLabel implements TableCellRenderer {
	
	int zaehler1;
	int zaehler2;
	Vector rowPflicht;
	Vector rowArt;
	Vector rowOption;
	int selection=0;
	double select=0;
	boolean stop = false;

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {
		
		if(column == 0)
		{
			JLabel label = new JLabel((String) value);
			return label;
		}else{
			
			if (rowArt.get(row).equals("DROP"))
			{
				Vector inhalt = new Vector();
				StringTokenizer tokenizer;
				tokenizer = new StringTokenizer((String) rowOption.get(row), "#");
				
				while (tokenizer.hasMoreTokens() == true){
					
					
					if(tokenizer.hasMoreTokens() == true)
					inhalt.add(tokenizer.nextToken());
					
					
				}
				
				
				if (value.equals(" "))
				{
					value = "0";
				}
				JComboBox combo = new JComboBox(inhalt);
				if (value instanceof String)
				{
				combo.setSelectedIndex(Integer.parseInt((String) value));
				}else if(value instanceof Double){
					
					
					while(stop == false)
					{
						if(value.equals(select))
						{
							stop = true;
						}else{
							selection++;
							select++;
							System.out.println(selection);
						}
						if(selection>100)
						{
							stop = true;
							selection = 0;
						}
						
					}
					
					combo.setSelectedIndex(selection);
				}
				
				return combo;
			} else if(rowArt.get(row).equals("CHECK"))
			{
				
				JCheckBox check = new JCheckBox();
				check.setEnabled(true);
				
				if (value.equals(1.0))
				{
					check.setSelected(true);
				}
				
				return check;
			}else{
				
				
				JLabel label = new JLabel(value.toString());
				return label;
			}
			
		
		
		
		}
	}

	
	//GETTER UND SETTER
	public int getZaehler1() {
		return zaehler1;
	}

	public void setZaehler1(int zaehler1) {
		this.zaehler1 = zaehler1;
	}

	public int getZaehler2() {
		return zaehler2;
	}

	public void setZaehler2(int zaehler2) {
		this.zaehler2 = zaehler2;
	}

	public Vector getRowPflicht() {
		return rowPflicht;
	}

	public void setRowPflicht(Vector rowPflicht) {
		this.rowPflicht = rowPflicht;
	}

	public Vector getRowArt() {
		return rowArt;
	}

	public void setRowArt(Vector rowArt) {
		this.rowArt = rowArt;
	}

	public Vector getRowOption() {
		return rowOption;
	}

	public void setRowOption(Vector rowOption) {
		this.rowOption = rowOption;
	}
	
	

}
```


Der Editor

```
package src;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;

public class MenuTableEditor extends AbstractCellEditor implements
		TableCellEditor, ActionListener {
	
	int zaehler1;
	int zaehler2;
	Vector rowPflicht;
	Vector rowArt;
	Vector rowOption;
	int selection=0;
	double select=0;
	boolean stop = false;
	Object currentValue;
	protected static final String EDIT = "edit";
	JComboBox combo;
	JCheckBox check;
	JTextField text;
	int action = 0;
	

	
	//Getter und Setter

	

	
	
	// Datenwiedergabe
	@Override
	public Object getCellEditorValue() {
		// TODO Auto-generated method stub
	//return currentValue;
		return "TEST";
		
	}
	
	public void actionPerformed(ActionEvent e)
	{
		System.out.println("ACTION!");
		
		if (action == 1){
		currentValue = combo.getSelectedIndex();
		System.out.println(currentValue.toString());
		
		} else if (action == 2){
			currentValue = check.toString();
			System.out.println(currentValue.toString());
			
		} else if (action == 3)
		{
			currentValue = text.getText();
			System.out.println(currentValue.toString());
		}
		System.out.println(action);
		
	}

	
	//Editor Designe
	@Override
	public Component getTableCellEditorComponent(JTable table, Object value,
			boolean isSelected, int row, int column) {
		// TODO Auto-generated method stub
		
		if(column == 0)
		{
			JLabel label = new JLabel((String) value);
			return label;
		}else{
			
			if (rowArt.get(row).equals("DROP"))
			{
				Vector inhalt = new Vector();
				StringTokenizer tokenizer;
				tokenizer = new StringTokenizer((String) rowOption.get(row), "#");
				
				while (tokenizer.hasMoreTokens() == true){
					
					
					if(tokenizer.hasMoreTokens() == true)
					inhalt.add(tokenizer.nextToken());
					
					
				}
				
				
				if (value.equals(" "))
				{
					value = "0";
				}
				combo = new JComboBox(inhalt);
				combo.setActionCommand(EDIT);
				combo.addActionListener(this);
				if (value instanceof String)
				{
				combo.setSelectedIndex(Integer.parseInt((String) value));
				}else if(value instanceof Double){
					
					
					while(stop == false)
					{
						if(value.equals(select))
						{
							stop = true;
						}else{
							selection++;
							select++;
							System.out.println(selection);
						}
						if(selection>100)
						{
							stop = true;
							selection = 0;
						}
						
					}
					
					combo.setSelectedIndex(selection);
				
				}
				action = 1;
				return combo;
			} else if(rowArt.get(row).equals("CHECK"))
			{
				check = new JCheckBox();
				check.setActionCommand(EDIT);
				check.addActionListener(this);
				
				check.setEnabled(true);
				
				if (value.equals(1.0))
				{
					check.setSelected(true);
				}
				action = 2;
				return check;
			}else{
				try{
					text = new JTextField();
					text.setActionCommand(EDIT);
					text.addActionListener(this);
					
					if (value instanceof String){
				
				text.setText((String) value);
				
				
					} else {
						
						text.setText(value.toString());
						
					}
					action = 3;
				return text;
				}catch (Exception e)
				{
					text = new JTextField();
					text.setActionCommand(EDIT);
					text.addActionListener(this);
					
					action = 3;
					
				return text;
				}
				
			}
	}

}
	

	public int getZaehler1() {
		return zaehler1;
	}

	public void setZaehler1(int zaehler1) {
		this.zaehler1 = zaehler1;
	}

	public int getZaehler2() {
		return zaehler2;
	}

	public void setZaehler2(int zaehler2) {
		this.zaehler2 = zaehler2;
	}

	public Vector getRowPflicht() {
		return rowPflicht;
	}

	public void setRowPflicht(Vector rowPflicht) {
		this.rowPflicht = rowPflicht;
	}

	public Vector getRowArt() {
		return rowArt;
	}

	public void setRowArt(Vector rowArt) {
		this.rowArt = rowArt;
	}

	public Vector getRowOption() {
		return rowOption;
	}

	public void setRowOption(Vector rowOption) {
		this.rowOption = rowOption;
	}
	}
```


Ich bin für jede Hilfe dankbar!

Sören


----------



## Camino (5. Feb 2012)

Was ist ein 
	
	
	
	





```
BI Projekt
```
?

Trotz deiner langen Beschreibung ist mir irgendwie unklar, was du da genau machen willst. Es gibt eine Exceldatei, die eine Spalte mit Werten hat. Diese Werte sollen in eine Java-GUI (JTable) übernommen werden?



> Mein Problem ist die GUI
> Wie gesagt ich habe pro "Menü" drei Vectoren
> Vector 1: Stellt eine Liste von Strings zu Verfügung die das Eingabefeld betiteln
> Vector 2: Spiegelt die eingegebenen Daten einer Spalte wieder... (also Strings oder Doubles... leere Felder sind automatisch " " oder 0.0)
> Vector 3: Gibt wieder was für ein Eingabetyp verwendet werden soll (also ob ein Textfeld verwendet werden soll, ob die Eingabe über eine Combobox laufen soll usw.)


Was bedeutet "Menü"? Warum es dafür 3 Vectoren gibt, versteh ich nicht. Vielleicht würde es reichen, sich 1 Datenstruktur (1 Klasse) zu überlegen, welche dann in einer Liste (ArrayList) gesamelt und dem TableModel zur Anzeige in der Tabelle übergeben werden kann.

Wie sehen denn die Daten aus, die von der Exceldatei übernommen werden sollen? Vielleicht vereinfacht sich das Problem, wenn du es mal von vorne herein anders/besser strukutrierst...


----------



## GUI-Programmer (5. Feb 2012)

OK, zu deinen eigentlichen Problem kann ich dir leider nichts sagen. Dafür reicht meine Erfahrung mit JTabel nicht aus.

Aber ein paar "Schönheitsfehler" liesen sich vermeiden:
Es ist unnötig, dass deine Klasse MenuTableRenderer von JLabel erbt. Außerdem könnte die actionPerformed von MenuTableRenderer auch so aussehen:

```
public void actionPerformed(ActionEvent e)
{
    System.out.println("ACTION!");
	switch(action) {
		case 1: currentValue = combo.getSelectedIndex(); break;
		case 2: currentValue = check.toString(); break;
		case 3: currentValue = text.getText(); break;
	}
	System.out.println(currentValue);
    System.out.println(action);
}
```
Wodurch dein Code insgesamt wiederum etwas übersichtlicher werden würde.

Evtl. macht es auch Sinn nicht von den abstrakten Klassen zu erben sondern von den "defaulten" Klassen zu erben, also:

```
public class MenuTableBuilder extends DefaultTableModel
```


```
public class MenuTableEditor extends DefaultCellEditor implements TableCellEditor, ActionListener {
```

Vielleich wird dadurch dein Problem ja schon gelöst.


----------



## DanZ (5. Feb 2012)

Ich denke das Problem ist, dass du die Methode "setValueAt" in deinem TableModel nicht überschrieben hast. Die JTable ruft diese Methode auf, nachdem sie von deinem Editor den Wert zurückgekriegt hat, aber weil dein Model dafür keine Logik hat geht das ins Nichts und die Tabelle bleibt unverändert...


----------



## MadBlue (5. Feb 2012)

Erstmal vielen Dank für die Antworten!

@ Danz: das ist ein guter Ansatz! Das werde ich mir sofort ansehen!

@ GUI-Programmer: Ja stimmt... in einigen Stellen war ich da wohl umständlich...
Das mit den Abstrakten klassen ist auch ein guter Ansatz!

@ Camino:

BI = Business Intelligence
Letzten endes soll das Tool hinterher beim strategischen Marketing helfen... ist aber jetzt fürs Programmieren unerheblich.

Die Tabelle schaut in etwa so aus:






Und hierraus soll sich die Anwendung ihre "Menüs" bauen.

Die Spalte A beinhaltet Informationen darüber ob es sich um ein Pflichtfeld handelt
Die Spalte B beinhaltet Information über den erwarteten Eingabewert (zum einem um die richtige Eingabekomponente bereit zu stellen, zum anderen zur Plausibilitätsüberprüfung...)
Die Spalte C beinhaltet weitere Optionen, bei DropDown Menüs zB. die einzelnen Optionen
die Spalte D beinhaltet die Namen der einzugebenen Daten
Ab Spalte E folgen die Datensätze

Vector 1 entspricht Spalte D (row1Data)
Vector 2 entspricht dem gerade aktiven Datensatz, also Spalte E oder höher (row2Data) (es soll immer nur EIN Datensatz abgebildet werden)
Vector 3 entspricht Spalte B (rowArt)

Die Texte CODE START und CODE END umklammern jeweils einen Eingabeblock... also in einer Table (oder einem Form oder sonst was) sollen also immer nur die dazwischen liegenden Felder angezeigt werden... ich habe das für mich als "menü" betitelt, obwohl es natürlich immer die gleiche Table bzw. das gleiche Form ist welches nur andere Daten läd.. - wenn ich die Form aufrufe gebe ich ihr mit welches Menü und welchen Datensatz ich nun eigendlich möchte... - bzw. ich gebe halt drei Vectoren mit welche eben direkt die passenden Informationen beherbergen... schien mir als das praktischste...

die Table für das 1. Menü und den 1. Datensatz könnte dann so aussehen: 




(mit weiter und zurück navigier ich in der Testanwendung dann durch die einzelnen "Datenhappen" des 1. Datensatzes...

Die JTable war wie gesagt nur mein "bester Einfall", allerdings hat das alles schlechter funktioniert als ich dachte, ich wollte nie einen Renderer oder einen Editor schreiben, aber anders hat es nicht so funktioniert wie ich wollte...

Daher bin ich auch für Lösungsansätze offen die ohne die Table auskommen!

Das Format der Excel ist aber leider weitgehend vorgegeben... der Sin dahinter soll der sein, das die BWLer das Tool hinterher selbstständig Pflegen und erweitern können... mit Excel kommen die gut klar... XML und dergleichen sind da meist Fremdwörter...

Als Ergebnis wird zudem uA. eine neue Excel Datei generiert... die eingegebenen Daten dienen also lediglich als Quelle für diverse Algorithmen, Heuristiken und Funktionen etc. die sich nicht mit Excel abbilden lassen...

Hoffe damit wirds nun etwas plastischer?

Sören


----------



## MadBlue (5. Feb 2012)

soooooo

es hat wirklich an der setValueAt Methode gelegen!
Er übernimmt jetzt die werte ins Table Model!

Okay er stellt noch etwas Unsin mit den Werten ab von der Combobox und der Checkbox, aber das bekomme ich glaube ich in den Griff!

Falls ihr noch einen Tipp habt bezüglich eines ActionListeners für das TextField welcher nicht unbedingt auf ein "Enter" wartet sondern das bloße aktualisieren reicht, wäre das einsame Spitze!

Sören

EDIT:
hmm... wenn ich eine eingabe nicht mit ENTER abschließe wird der vorher zuletzt gesetzte Wert in jede Zelle eingefügt welch ich anwähle... Werte aus der Combobox und des Select feldes werden in selbige  gar nicht übernommen, sondern nur in andere Felder die ich anwähle... so dann das alles noch nicht richtig sein... ich bekomm noch graue Haare an dem Teil...


----------



## DanZ (5. Feb 2012)

Ist so schwer zu sagen. Kannst du vielleicht nochmal den aktuellen Source posten und am besten sagen, wie man da am einfachsten Daten reinkriegt?


----------



## bERt0r (5. Feb 2012)

Du musst dir bei sämtlichen Methoden im Tablemodel und im Editor durchlesen, was die laut Javadoc machen sollen und sie dementsprechend überladen. Von sich aus kann das AbstractTableModel nämlich so gut wie gar nix.


----------



## MadBlue (5. Feb 2012)

ohje ohje... mir schwant da böses...

Lohnt das vom aufwand denn überhaupt? Ist es da nicht einfacher (dynamisch) textfelder, comboboxen und Checkboxen in die Form zu ziehen? Bzw. habt ihr ne Idee wie so ein Ansatz aussehen könnte?

@ DanZ

Der Code schaut nun so aus


```
package src;

import java.util.Vector;

import javax.swing.table.AbstractTableModel;

public class MenuTableBuilder extends AbstractTableModel {
	
	int zaehler1;
	int zaehler2;
	//spalte 1, nicht beschreibbar
	Vector row1Data;
	//spalte 2, entspricht den bereits eingetragenen Daten, soll editierbar sein
	Vector row2Data;
	//Pflichtfelder, irrelevant, nocht nicht implementiert
	Vector rowPflicht;
	//gibt das Format an (Textfeld, Combobox, etc.)
	Vector rowArt;
	//evntl. Optionen... zB. bei der combobox)
	Vector rowOption;


	
	public boolean isCellEditable(int row, int col)
	{
		if(col == 1){
		return true;
		}else
		{return false;}
	}
	
	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return zaehler2;
	}
	

	@Override
	public int getRowCount() {
		// TODO Auto-generated method stub
		return zaehler1;
	}
	
	@Override
	public void setValueAt(Object value, int row, int col) {
        
		row2Data.set(row, value);
		
        fireTableCellUpdated(row, col);
	}

	@Override
	public Object getValueAt(int row, int col) {
		// TODO Auto-generated method stub
		
		
		if(col==1){
			try {
			if ((Double) row2Data.get(row) == 0)
			{
				return "";
			}
			else {
				return row2Data.get(row);
				}
			}catch (Exception e)
			{
				return row2Data.get(row);
			}
			
					
			
		} else {
			
			
			
			return row1Data.get(row);
		}
		
	}
	
	
	
	
	//GETTER UND SETTER


	public int getZaehler1() {
		return zaehler1;
	}


	public void setZaehler1(int zaehler1) {
		this.zaehler1 = zaehler1;
	}


	public int getZaehler2() {
		return zaehler2;
	}


	public void setZaehler2(int zaehler2) {
		this.zaehler2 = zaehler2;
	}


	public Vector getRow1Data() {
		return row1Data;
	}


	public void setRow1Data(Vector row1Data) {
		this.row1Data = row1Data;
	}


	public Vector getRow2Data() {
		return row2Data;
	}


	public void setRow2Data(Vector row2Data) {
		this.row2Data = row2Data;
	}


	public Vector getRowPflicht() {
		return rowPflicht;
	}


	public void setRowPflicht(Vector rowPflicht) {
		this.rowPflicht = rowPflicht;
	}


	public Vector getRowArt() {
		return rowArt;
	}


	public void setRowArt(Vector rowArt) {
		this.rowArt = rowArt;
	}


	public Vector getRowOption() {
		return rowOption;
	}


	public void setRowOption(Vector rowOption) {
		this.rowOption = rowOption;
	}
	

}[/Java]

würde es was bringen wenn ich die Testanwendung "kompiliert" online stelle? (alternativ auch den Workspace oder das Package)

Wie gesagt, als ich die Tabelle als Eingabe-Komponente gewählt habe war mir nicht klar dass, das sooooooooo kompliziert werden würde... ich dachte man verändert das TableModel so das sich dieses aus den Vectoren die passenden Zeilen und Spalten zusammenbaut, weist einzelnen Zellen die Komponente zu (was ja leider nur spaltenweise geht...) und fertig ist... wo ich jetzt stehe ist weit, weit über dem wo ich eigendlich hin wollte!

Sören
```


----------



## bERt0r (5. Feb 2012)

Du hast da eine komplette falsche Vorstellung davon, was ein TableModel ist. Schau dir mal ein Tutorial an.[EDIT]Schau mal in die FAQ Sektion[/EDIT]


----------



## Camino (6. Feb 2012)

Keine Ahnung. Mir ist die erwünschte Struktur, die in das TableModel übernommen werden soll, immer noch völligst unklar.


----------



## MadBlue (6. Feb 2012)

Hm...

vom Prinziep her hätte mir das standard Modell ausgereicht.
Ich kann ja der JTable beim erzeugen Vectoren mit geben...

Mein Problem, wieso ich das nicht getan habe ist, das in meinen Vectoren spalten stehen, keine Zeilen und der Constructor der JTable das genau anders herum haben will...

sprich ich habe einen Vector 1 mit der Spalte eins (jeder Wert ist eine Zeile) und Vector 2 mit der zweiten Spalte (wieder, jeder Wert ist eine Zeile...)

Das ist für mich wichtig weil ich weiß wie viele Spalten ich habe (immer nur 2) aber nicht wie viele Zeilen (5-20)

Oder was meinst du mit der Struktur?

(Mit dem eigenem Renderer und dem eigenem CellEditor habe ich wiederum nur angefangen weil es nicht möglich ist einzelnen Zellen einen bestimmten Renderer/Editor zuzuweisen, sondern nur ganzen spalten...)

@ bERt0r:
Aus dem FAQ hab ich schon einiges raus genommen... ich zieh mir das nun nochmals rein...
Aber ja du hast wohl insofern recht das ich mir der Tragweite des TableModels nicht im klaren wahr... das Teil komplett neu zu konfigurieren übersteigt aber wahrscheinlich  meine Kapazitäten...

ich geh wohl besser nochmal in mich und überlege ob es irgend eine Möglichkeit gibt die Mitgelieferten Komponenten zu verwenden...

Sören


----------



## Camino (6. Feb 2012)

Hmm, so wie ich das sehe (und hoffentlich verstehe) willst du in jeder Tabelle ("Menü") jeweils einen Datensatz anzeigen. Und dann mit deinen Buttons "weiter" oder "zurück" in diesen Datensätzen blättern. Mit Struktur meinte ich, dass du eine Klasse anlegst, die 1 Datensatz darstellt und die Felder dieses Datensatzes enthält. Dann kannst du dir eine Liste mit Objekten dieser Klasse anlegen (jedes Objekt entspricht 1 Datensatz) und kannst durch diese Liste durchgehen und dir immer 1 Datensatz anzeigen.


----------



## MadBlue (6. Feb 2012)

Ja das hast du soweit richtig verstanden...

wobei die kleine Anwendung mit dem "weiter" und "zurück" Button mehr eine Testanwendung war...
Die Programmlogik dieses Programmteils soll in etwa so aussehen


"Startpunkt"
Liste mit Übersicht der "Datensätze" (dafür habe ich eine JList genommen)
Hier würden im besagten beispiel dann "Region 1", "Region 2", und "Region 3" aufgeführt...
ich wähle hier einen Datensatz aus (zB. "Region 1") 

Nach der Wahl des Datensatzes soll dieser Datensatz einmal mit der Tabelle Häppchen weise durchlaufen werden. Da der User hier bis zu 1200 Werte eingeben kann/soll sind die anderen Datensätze auch erstmal uninteressant. Ich lade auch immer nur jedes Häppchen aus der Datei sobald es abgefragt wird...
(da behelfe ich mich halt mit diversen Zählern usw. ... halt ganz kleines Programmieren 1mal1... aber das funktioniert alles problemlos... ich kann in meiner Testanwendung auch problemlos mit weiter und zurück durch die Tabellen springen... das hat alles soweit gut funktioniert) Probleme gibt es halt sobald man Daten in die rechte Spalte eingibt. (Die linke ist ja eh nicht editierbar)

Bei jedem klick auf "weiter" oder "zurück" soll der geänderte Tabelleinhalt der rechten Spalte zurück in die excel Datei (zu dem entsprechenden Datensatz) geschrieben werden. Dazu muss nur der Vector, aus dem ich die Tabelle gebaut habe geändert werden und meiner entsprechenden Funktion übergeben werden welche in die Excel Datei schreibt... den ganzen Excel lesen und schreiben mist habe ich bereits fertig und das tut es alles auch erstaunlich problemlos...

Das ganze soll dann noch mit Plausibilitätsüberprüfung aufgepeppt werden (wurde ein String oder ein Double eingegeben, wurden Werte dieser Größenordnung erwartet, wurde ein Pflichtfeld freigelassen etc.) aber das ist Beiwerk, die grundlegende Funktion in die richtige Stelle der Tabelle zu schreiben versagt ja schon...

Sören


----------



## Camino (6. Feb 2012)

Das bedeutet, du willst die Daten in der Excel-Tabelle halten/speichern, und die Java-Anwendung soll darauf zugreifen (also auslesen und geänderte Daten zurück in die Excel-Datei schreiben)?


----------



## MadBlue (6. Feb 2012)

Ganz genau


----------



## Camino (6. Feb 2012)

Sorry, aber da weiss ich leider auch nicht weiter, wie das am besten funktioniert. Oder ob das überhaupt (einfach) funktioniert. Eine Möglichkeit, die Daten anstatt in der Excel-Datei in einer Datenbank zu halten hast du nicht?


----------



## MadBlue (6. Feb 2012)

na wo wäre da jetzt der unterschied die JTable betreffend?? Ich seh nicht ganz wo die relevanz liegt was vor und nach der Table mit den daten passiert, wie gesagt der Excel-Programmteil ist schon fertig... ich bekomme Vectoren mit daten geliefert und es reicht wenn die JTable diese bearbeitet...

Ich habe doch bereits Klassen welche die Daten aus der Excel auslesen und auch wieder rein schreiben programmiert... die müssen auch nicht unbedingt in einem Vector landen... welches Format wäre denn besser?

Vom Prinzipien her bin ich da öllig frei, die Methode läd halt Strings bzw. Doubles aus der Excel und schreibt diese wieder zurück... den Vector hab ich nur genommen um so einen ganzen Schwung davon zu transportieren..

Ich verzweifel an der JTable, nicht an dem Excel Part... 


Ich muss auf jedenfall was "lokales" verwenden... eine Datenbank ist nicht drin, das Teil muss hinterher OutOfTheBox laufen... alternativ könnte ich auch XML nehmen... aber das würde die Erweiterbarkeit des Programms zu stark einschränken... zudem liegt die ExcelDatei in dem Format so ca. schon vor... alles andere müsste ich noch mühsam erstellen... 1200 Zeilen sind halt auch nicht ohne...

Sören


----------



## Camino (6. Feb 2012)

Ah, OK, wenn das mit dem Excel auslesen und wieder reinschreiben funktioniert... Ich schau nochmal, ob ich erkennen kann, woran es mit der JTable haken könnte...


----------



## Camino (6. Feb 2012)

Ich vermute mal, dass es daran liegen könnte, dass du so viele Vectoren benutzt. Am besten 1 Datenstruktur pro Datensatz, in dem die Daten drinstehen, also eine Klasse mit den Feldern, die du pro Datensatz benötigst. Dann kannst du dir die Daten aus der Excel in diese Struktur reinladen, ändern und wieder zurückschreiben.


----------



## MadBlue (6. Feb 2012)

jau... das wäre echt super!

Oder vielleicht hast du ja eine andere Idee wie ich den Vector (mit unbestimmter länge) gescheit bearbeiten kann...

wie gesagt es dreht sich im großen und ganzen um drei Vectoren die ca, so aussehen

Vector 1 Zeilennamen [Umsatz, Gewinn, Aktiv ...]
Vector 2 Daten          [100, 200, 1, ...]
Vector 3 Feldart        [Textfeld, Textfeld, Checkbox, ...]
(der erste Wert des 1. Vectors gehört zum 1. Wert der anderen beiden Vectoren, der 2. Wert des 1. Vectors zum 2. Wert der anderen beiden usw.)

wichtig ist das der 2. Vector mittels GUI verändert wirden kann... am besten so das immer der Name zum passendem Wert sichbar ist und der Wert mittels dem Festgelegten Werkzeug bearbeitet wird... sprich

JLabel[Umsatz]            JTextfield[100]
JLabel[Gewinn]            JTextfield[100]
JLabel[Aktiv]               JCheckbox[1/true/checked]
...                             ...

Ob das jetzt in einer Table passiert oder direkt in einem Form oder sonst wo ist mir relativ gleichgültig. Mir erschien die Tabelle als praktisch weil ich selber keine Ahnung hatte wie ich das sonst so dynamisch implementieren soll wenn ich vorher nicht weiß wie viele dieser Komponenten anfallen und wie sie aussehen sollen...

Sören


----------



## Camino (6. Feb 2012)

Aber die Zeilen (Umsatz, Gewinn, Aktiv...) sind doch bekannt und ändern sich nicht von Datensatz zu Datensatz? Und anstatt den 3 Vectoren brauchst du nur 1 Collection bzw. 1 Klasse mit den Feldern des 1 Datensatzes, weil ja die Werte der verschiedenen Vectoren zusammenhängen.


----------



## MadBlue (6. Feb 2012)

Camino hat gesagt.:


> Ich vermute mal, dass es daran liegen könnte, dass du so viele Vectoren benutzt. Am besten 1 Datenstruktur pro Datensatz, in dem die Daten drinstehen, also eine Klasse mit den Feldern, die du pro Datensatz benötigst. Dann kannst du dir die Daten aus der Excel in diese Struktur reinladen, ändern und wieder zurückschreiben.





hmmm.. das glaub ich weniger... wenn ich nur mein TableModel verwende und meinen Renderer und meinen Editor nicht setze funktioniert es nähmlich...

Natürlich werden dann alle Felder als Textfelder angezeigt... aber die Daten werden Problemlos dahin übernommen wohin sie übernommen werden sollen...

Sören

EDIT;
Ja die daten aus dem 1. und 3. Vector sind bekannt... die werden ja auch nur gelesen... in die Excel-Tabelle rein schreiben tu ich ausschließlich den 2. Vector... und ist es nur die 2. Spalte in der JTable die bearbeitet werden soll!

Das zurück schreiben des Vectors funktioniert auch... nur mein TableEditor schreibt mir die Werte nicht an die Stelle der JTable an der ich sie haben möchte...

Sören


----------



## Camino (6. Feb 2012)

MadBlue hat gesagt.:


> hmmm.. das glaub ich weniger... wenn ich nur mein TableModel verwende und meinen Renderer und meinen Editor nicht setze funktioniert es nähmlich...
> 
> Natürlich werden dann alle Felder als Textfelder angezeigt... aber die Daten werden Problemlos dahin übernommen wohin sie übernommen werden sollen...



Der Renderer ist ja nur dafür da, wie die Zellen dargestellt werden sollen, also eher so Formatierungs- und Farbenzeugs. Der Editor wegen der Eingabe der Daten. Wenn du nun ein TableModel mit einer Datenstruktur hast, kannst du auch darüber die Daten eingeben und speichern und diese Datenstruktur dann in die Exceldatei übertragen. Es gibt bei dem TableModel eine Methode, welche die Daten in der Tabelle darstellt, und eine Methode, welche die eingegebenen Daten annimmt. Und eine Methode, die sagt, ob eine Zelle editierbar ist oder nicht. Dann speichert man die eingegebenen Werte in der Datenstruktur und schreibt diese Daten dann in die Excel-Datei.


----------



## bERt0r (6. Feb 2012)

Ich würde das an deiner Stelle so machen: Eine Klasse Tabelleneintrag mit den Attributen String art, String name und ein 3er Object Array region.
Beim einlesen bzw. aus deinen Vektoren machst du dann z.B ein new Tabelleineintrag("Titel","Portfolio -fit",{"100","200","300"});


----------



## DanZ (6. Feb 2012)

Also ich schließe mich den anderen an und würde dir auch empfehlen die Daten vernünftig in Klassen zu kapseln. Das löst zwar dein Problem erstmal nicht aber dadurch wird es sehr viel einfacher den Überblick zu behalten und die Fehler zu finden. Momentan könnte der Fehler zwischen dem falschen Setzen der Daten und dem fehlerhaften Benutzen der Schnittstelle halt überall liegen. Das ist zwar erstmal noch ziemlich Arbeit aber spätestens wenn du die noch ausstehenden Sachen(Plichtfeld etc.) implementierst, wirst du es dir danken!
Außerdem wäre es eventuell geschickt für jede Art (Textfeld, Combobox, Checkbox) eigene Renderer/Editoren zu schreiben. Wenn einer jeweils nur eine Aufgabe hat gerät man mit Datentypen, Casts und verschachtelten If Anweisungen nicht so leicht durcheinander.
Was mir grad zu dem Problem mit Checkboxes und Comboboxes noch aufgefallen ist:

Im Editor gibst du die Werte folgendermaßen zurück:


```
currentValue = combo.getSelectedIndex();
currentValue = check.toString();
```

Also für die Combobox ein int und für die checkBox einen String(letzteres ist an sich schon etwas sinnlos)

Im Renderer ließt du sie aber so wieder aus:


```
if (value.equals(1.0)) {
                    check.setSelected(true);
}
```

Und für die Combobox irgendeinen komplizierten Kram mit String und Double. 

Mit den Datentypen, die vom Editor über das Tablemodel gesetzt werden, kann der Renderer also überhaupt nichts anfangen... Das wird ein Grund sein warum das nicht funktioniert.

Ansonsten kann ich leider nicht so viel dazu sagen, weil du nur den neuen Source des Tablemodels gepostet hast. Ich bräuchte schon etwas lauffähiges um es auszuprobieren.


----------



## MadBlue (6. Feb 2012)

Wenn ich für jeden Datentyp einen eigenen Renderer erstelle... wie kann ich diesen denn den einzelnen Zellen zuweisen? Das hätte ich natürlich von Anfang an lieber gemacht. Aber soweit ich JTable geblickt habe geht das nur spaltenweise, und das bringt mir ja nichts...

Und ich versteh nicht ganz was du mit Kapseln meinst... - ich habe eine klasse die aus dem großen Excel wust drei Vectoren bereit stellt... wieviel kleiner soll das denn werden? Es muss doch möglich sein aus zwei Vectoren (Spalte 1 und Spalte 2) eine JTable zu bauen ohne das direkt die Hütten brennt?

@ bERt0r:

Der Sinn geht jetzt leider total an mir vorbei...

Wieso denn ein 3er Array? Pro Eintrag ist doch nur ein Wert erforderlich? Oder willst du da direkt alle Datensätze erfassen? Aber dann funktioniert kein Array... es können statt der drei gezeigten ja auch 10 oder 60 Datensätze daraus werden... und afaik kann ich arrays nicht so einfach vergrößern...

@ll:
Der Hauptfehler scheint im CellEditor zu liegen... schalte ich den ab so das JTable den eigenen Editor verwendet, so geschieht die Eingabe zwar immer über ein Textfeld aber die Daten kommen an. Sogar die Comboboxen zeigen die richtige Option an wenn ich den passenden Wert in das TextField eingebe...

Sören

EDIT:

Wegen was lauffähigem... wie ist das denn für dich übersichtlicher? Soll ich den Source aller beteidigten Klassen posten? Oder das Projekt exportieren und bereitstellen? Was hilft da am meisten?


----------



## Camino (6. Feb 2012)

MadBlue hat gesagt.:


> Und ich versteh nicht ganz was du mit Kapseln meinst... - ich habe eine klasse die aus dem großen Excel wust drei Vectoren bereit stellt... wieviel kleiner soll das denn werden? Es muss doch möglich sein aus zwei Vectoren (Spalte 1 und Spalte 2) eine JTable zu bauen ohne das direkt die Hütten brennt?



Das ist vielleicht das Problem, dass du das so mit den 2 Vectoren (Spalte 1 und 2) machst. Die Werte einer Zeile gehören doch zusammen. Also würde ich die auch in einer Collection zusammenfassen, z.B. als HashMap<Key, Value> oder eine eigene Klasse erstellen mit den Feldern String und Double für Bezeichnung und Werte und die erstellten Objekte dann in einer ArrayList zusammenfassen. Oder gleich eine Klasse schreiben, welche genaue einen Datensatz enthält. Dann kannst du mit getter- und setter-Methoden arbeiten und die Daten aus der Exceldatei holen und wieder zurückschreiben.


----------



## MadBlue (6. Feb 2012)

wahrscheinlich ist das wirklich eleganter... aber ich denke nicht dass das mein aktuelles Problem ist...

ich denke ich habe den TableCellEditor falsch implementiert und auch beim Renderer unsauber gearbeitet. (wobei der es ja trotzdem tut...)

Sören


----------



## bERt0r (6. Feb 2012)

Ich dachte dass es immer nur 3 Regionen gibt. Wenn es mehr sind kannst du auch einen Vector stat dem array verwenden. Ich wollte damit zum ausdruck bringen, dass du pro Zeile in deiner Exceltabelle ein Objekt anlegst, und dieses kannst du dann sehr bequem in deinem Tablemodell verarbeiten.


----------



## DanZ (6. Feb 2012)

MadBlue hat gesagt.:


> Wenn ich für jeden Datentyp einen eigenen Renderer erstelle... wie kann ich diesen denn den einzelnen Zellen zuweisen? Das hätte ich natürlich von Anfang an lieber gemacht. Aber soweit ich JTable geblickt habe geht das nur spaltenweise, und das bringt mir ja nichts...


Du hast natürlich vollkommen recht da hab ich kurz nicht mitgedacht.

Versuch doch mal im Renderer und im Editor (sowie auch in den Klassen die den Kram aus Excel lesen) die richtigen Datentypen zu verwenden. Das heißt für die CheckBox boolean und für die ComboBox entweder den Index oder den Value (aber konsistent das gleiche). 

Zum kapseln: Wie oben schon vorgeschlagen, ich würd erstmal eine Klasse für jede Zeile machen. Je nach deinem Kenntnisstand könnte man das noch weiter splitten (e.g. Klasse für Datentyp, Region, Menü) und die dann entsprechend verbinden und ggf. Generics nutzen oder an den entsprechenden Stellen mit Vererbung arbeiten. Aber das macht momentan nur Sinn, wenn das für dich nicht noch mehr Verwirrung bringt.
Also fürs erste eine Klasse "DataRow" oder so mit den entsprechenden Attributen. : Name des Felds, Wert des Feld, Art des Feld(evt. als enum, dann kannst du ein schönes switch machen),usw. Und ins TableModel packst du dann eine List<DataRow> bzw. Vector<DataRow>, was dir lieber ist.



MadBlue hat gesagt.:


> EDIT:
> 
> Wegen was lauffähigem... wie ist das denn für dich übersichtlicher? Soll ich den Source aller beteidigten Klassen posten? Oder das Projekt exportieren und bereitstellen? Was hilft da am meisten?



Am besten das ganze Projekt insgesamt bereitstellen... 10 Klassen zusammenpasten macht wenig spaß


----------



## MadBlue (8. Feb 2012)

So,

ich war die letzten zwei Tage datentechnisch von der Außenwelt abgeschnitten... darum gibts die Daten erst heute:


exportiertes Project: main.derbe-frisiert.com/kubina/bi_project.zip

Beispiel ExcelDatei: main.derbe-frisiert.com/kubina/workon.xls

Überflüssige Klassen hab ich der übersichthalber nicht mit exportiert...
In dem Projekt verwende ich das Framework apache POI...
Apache POI - Download Release Artifacts

in der GUI Klasse TableTesterApp ist direkt am Anfang von initialize() der Pfad zur Excel Datei zu setzen...
Damit müsste es eigendlich schon funktionieren...

Ich hoffe der Code ist nich zu arg unleserlich und chaotisch... der war natürlich nie dafür gedacht mal von wem anders außer von mir gelesen zu werden, und da ich kein Programmierer bin, musste ich selber auch etwas mit dem Projekt wachsen... vieles würde ich im Nachhinein auch eleganter lösen 

Auf jedenfall schonmal besten Dank für eure Mühen!
An vielen Ecken habt ihr mir ja schon gut geholfen!

Sören


----------



## DanZ (8. Feb 2012)

Also Umlaute im Code sind generell eine eher schlechte Idee  aber gut, kann man ja rauslöschen

Ich hab jetzt den Faden etwas verloren - was genau funktioniert jetzt alles nicht?

Ich hab den Code vom Editor wie unten angepasst. Damit funktioniert das Editieren meines Erachtens(wird natürlich nicht Datensatzübergreifend gespeichert, aber ich kann im Code auch nicht erkennen, dass das schon funktionieren sollte). Schön ist das trotz allem nicht, aber ob du deine Datenstruktur ändern willst liegt an dir.


```
@Override
	public Object getCellEditorValue() {
		// TODO Auto-generated method stub
        switch(action) {
        case 1: currentValue = combo.getSelectedIndex()+""; break;
        case 2: currentValue = check.isSelected()?1.0:0.0; break;
        case 3: currentValue = text.getText(); break;
    }
	return currentValue;
		//return "TEST";
		
	}
	
	public void actionPerformed(ActionEvent e)
	{
		System.out.println("ACTION!");
		fireEditingStopped();
		
	}
```

So eine Frage nebenbei: Wenn du kein Programmier bist, warum musst du dann so ein doch recht umfangreiches Projekt coden?


----------



## MadBlue (8. Feb 2012)

das zurück geben in den Datensatz ist noch nicht implementiert... wenn die Daten korrekt in der JTable ankommen sollte ich das aber hin bekommen.

was nicht funktioniert hat war folgendes:
1. Das übernehmen der Werte aus Checkboxen und DropDown Menüs (zB. seite 2 der Testanwendung, sprich einmal auf "weiter")
2. Wenn ein wert einmal übernommen wurde, hat er sich danach in alle Zellen geschrieben die ich ausgewählt, aber nicht mit Enter bestätigt habe (also wenn ich 2-3 Zellen einfach nur anklicke, hat er da Werte rein geschrieben die da nicht rein sollten)

Das waren die Hauptprobleme...


Und das ist eine gute Frage...
Ich bin werdender Wirtschaftsinformatiker... das Projekt was ich bearbeite ist gigantisch und hat einen Workload von etwa einem halben Jahr. 80% davon sind aber BWL und Statistik. Der Teil Programmieren der da drin steckte sah "so gerade irgendwie schaffbar" für mich aus. Aber das war bevor ich mich mit GUIs in Java auseinander gesetzt habe. (Alles was ich sonst bisher geschrieben habe, hatte entweder kein GUI oder es waren eh Webanwendungen und ich hab mit JSP gearbeitet, aber das waren auch alles nur kleine Sachen)

Wir haben natürlich auch Vorlesungen in Programmieren, Software-Engineering, Datenbanken usw. aber an die Ausbildung eines guten Fachinformatiker-Anwendungsentwicklers kommt das nicht heran, daher seh ich mich nicht als Programmierer. 

Sören


----------



## MadBlue (8. Feb 2012)

So ich habe gerade deine Code Änderungen bei mir eingefügt udn es funktioniert! Damit bist d definitv mein Held der diesigen Woche!! Sau stark besten Dank!

Über die Datenstruktur grübel ich schon nach... ich denke da werde ich nochmal etwas aufräumen!

Sören


----------



## DanZ (8. Feb 2012)

Kein Problem, freut mich wenn ich dir helfen konnte 

Wenn du noch die Zeit dafür hast würde ich dir das aufjedenfall empfehlen. Zum einen, weil wie gesagt die weiteren Implementierungen dadurch viel einfacher werden und zum anderen, weil eine saubere Programmstruktur (grade wenn es durch ein Refactoring entsteht) das Verständnis des grundlegenden Konzepts unglaublich stärkt... und dann gehts das nächste mal (falls du nochmal mit sowas in Kontakt kommen solltest, aber ganz darum herumkommen wirst du wohl nicht, vermute ich) deutlich schneller.

Aber ist interessant mal auf einen "richtigen" Wirtschaftsinformatiker zu treffen. Alle, die ich kenne, haben eigentlich den Schwerpunkt Informatik und haben BWL dazugenommen, um irgendwas mit Geld zu machen bzw. später mehr zu verdienen.


----------



## MadBlue (12. Feb 2012)

Hallo,
ich nochmal...

ich habe mich nun dran gegeben und wollte das zurück Schreiben in die ExcelDatei implementieren... halt über einen Button "speichern" in der Testanwendung selber (neben weiter und zurück...) - Das Funktioniert auch soweit das die JTable welche ursprünglich erstellt wurde wieder in die Excel an die richtige Stelle gesichert wird. Die durch die Eingabe geänderten Informationen bleiben jedoch auf der Strecke, also das JTable Objekt scheint nicht aktualisiert zu werden... wie komm ich an die aktualisierte JTable heran?

Sören

EDIT:

ich war etwas zu voreilig... der Fehler liegt wo anders... *weiter such*
EDIT: Fehler gefunden und nun funktioniert es... na Gott sei Dank... so langsam wird ein Schuh drauß 

Allerdings hoffe ich inständig das ich nie wieder Java eigene GUI verwenden muss... :rtfm:


----------

