Ein JOptionPane.showMessageDialog(.)

Status
Nicht offen für weitere Antworten.

bliko

Mitglied
Ich habe hier eine grafische Darstellung eines binären Suchbaumes versucht zu programmieren. Wenn der Baum eine Höhe(=Tiefe) von 4 hat soll eine Meldung ausgegeben werden, dass der Baum bereits die Höhe soundso hat, es kann nichts mehr eingefügt werden.
Es funktioniert auch alles ganz gut, nur wird beim Schließen des Fensters auch der bereits gezeichnete Baum überzeichnet, bzw. gelöscht, der soll aber bleiben, dafür soll es dann später noch einen eigenen Clear-Button geben.
Ich bin mir sicher, dass das etwas mit den panels zu tun hat, komme aber nicht wirklich weiter. Könnte mir da jemand vielleicht weiterhelfen? Danke im voraus.
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BinBaumPanel extends JPanel implements ActionListener{
	private BinBaum_grafisch b;
	private int[] feld = {4,3,7,8,6,3,2,1,0,9,10,5,12};
	private JButton enter, loeschen;
	private JLabel l1;
	private JTextField t1;
	private Dimension d = new Dimension(50,27);
	private int s, x_akt, y_akt, e_akt, x_Pos, y_Pos;
	private int x_Prev, y_Prev, versatz_s, versatz_l, max_hoehe;
	private Font f = new Font("Verdana", Font.BOLD, 12);
	JPanel p1, p2;
	
	public BinBaumPanel(){
		b = new BinBaum_grafisch();
		x_akt = 200;
		y_akt = 80;
		e_akt = 0;
		versatz_l = 5;
		max_hoehe = 4;
		l1 = new JLabel("Geben Sie eine ganze Zahl >=0 ein:", SwingConstants.RIGHT);
		t1 = new JTextField("");
		t1.setPreferredSize(d);
		t1.addKeyListener(new MyKL());
		enter = new JButton("EINGEBEN");
		enter.addActionListener(this);
		add(l1);
		add(t1);
		add(enter);
	}
	
	public void ausgeben(int[] f){
		Graphics g = getGraphics();
		f = feld;
		//einfuegenFeld(f);
		
		for (int i=0; i<feld.length; i++){
			if (i==feld.length)break;
			int vorg = b.findeVorgaenger(feld[i], feld[i]);
			x_Pos = b.getX(feld[i], x_akt, e_akt);
			x_Prev = b.getX(vorg, x_akt, e_akt);
			y_Pos = b.getY(feld[i], y_akt, e_akt);
			y_Prev = b.getY(vorg, y_akt,e_akt);
			
			if (x_Pos < x_Prev){
				versatz_s = 7;
			}
			else {
				versatz_s = 0;
			}
			String s = String.valueOf(feld[i]);
			
			g.drawString(s, x_Pos-versatz_s, y_Pos);
			g.drawLine(x_Prev, y_Prev, x_Pos, y_Pos);
		}
	}	
	
	public void paintComponent (Graphics grafik)
	{
		super.paintComponents(grafik);
		grafik.setColor(Color.lightGray);
		
		// Horizontale Rasterlinien
		for (int y=0; y<this.getHeight(); y+= 40){
			grafik.drawLine(0,y,400,y);
		}
		
		// Vertikale Rasterlinien
		for (int x=0; x<getHeight(); x+= 20){
			grafik.drawLine(x,40,x,500);
		}
	}
	
	/**
	 * Fügt die Schlüssel des Feldes vom Typ int[] in
	 * den Suchbaum ein;
	 * @param feld das Feld von Schlüssel;
	 */
	public void einfuegenFeld(int[] feld){
		for (int i=0; i<feld.length; i++){
			b.einfuegen(feld[i]);
		}
	}
	
	public void einfuegenSchluessel(int schluessel){
		int s = Integer.parseInt(t1.getText());
		b.einfuegen(s);
	}

das hier ist die Methode, die jedes Mal, wenn eingefügt wird, aufgerufen wird. Überschreitet der Baum eben eine bestimmte Höhe, so soll eine Nachricht ausgegeben werden, ohne dass der bereits gezeichnete Baum überzeichnet wird bzw. beim Schließen verschwindet.
Code:
	public void zeichneSchluessel(int schluessel){
		Graphics g = getGraphics();
		int s = schluessel;
		b.einfuegen(s);
		int h = b.getHoehe();
		System.out.println(h);
		if(b.getHoehe()>max_hoehe){
			String info = "<HTML><BODY>Der Baum hat bereits " +
						  "die Höhe " + max_hoehe
						  + ".
Es können keine weiteren Schlüssel " 
						  + "eingefügt werden!</BODY></HTML>";
			JPanel jp = new JPanel();
			jp.setLocation(50, 50);
			JOptionPane.showMessageDialog(jp, info);
			return;
		}
		
		int vorg = b.findeVorgaenger(s, s);
		x_Pos = b.getX(s, x_akt, e_akt);
		x_Prev = b.getX(vorg, x_akt, e_akt);
		y_Pos = b.getY(s, y_akt, e_akt);
		y_Prev = b.getY(vorg, y_akt,e_akt);
		
		FontMetrics fm = getFontMetrics(f);
		String s_zahl = String.valueOf(s);
		int s_breite = fm.stringWidth(s_zahl);
		versatz_s = (int) Math.round(s_breite/2);
		
		//Umwandeln des Schlüssels vom Typ int in
		//einen String und Ausgabe der Zahl und der Linien
		String zahl = String.valueOf(s);
		if (h==1){
			g.drawString(zahl, x_Pos-versatz_s, y_Pos+versatz_l);
		}
		else{
			g.drawString(zahl, x_Pos-versatz_s, y_Pos+versatz_l);
			if (x_Prev > x_Pos){
				g.drawLine(x_Prev-versatz_l, y_Prev+versatz_l, x_Pos+versatz_l, y_Pos-versatz_l);
			}
			else{
				g.drawLine(x_Prev+versatz_l, y_Prev+versatz_l, x_Pos-versatz_l, y_Pos-versatz_l);
			}
		}	
	}

Mittels des ActionListener bzw. des KeyListener werden die Ereignisse ausgelöst
Code:
	/**
	 * Gibt den Ebenenabstand auf der y-Achse zurück
	 */
	
	public int getEbenenAbstand(){
		return b.getEbenenAbstand();
	}
	
	public void actionPerformed(ActionEvent e){
		Object source = e.getSource();
		if (source == enter){
			int h = b.getHoehe();
			System.out.println(h);
			if(b.getHoehe()>max_hoehe){
				String info = "<HTML><BODY>Der Baum hat bereits " +
							  "die Höhe " + max_hoehe
							  + ".
Es können keine weiteren Schlüssel " 
							  + "eingefügt werden!</BODY></HTML>";
				JPanel jp = new JPanel();
				JOptionPane.showMessageDialog(jp, info);
				//repaint();
				//new HelloSwingFrame();
				return;
			}
			if(t1.getText().equals("")){return;}
			else{
				System.out.println("Enter gedrückt!");
				zeichneSchluessel(Integer.parseInt(t1.getText()));
			}
			//ausgeben(feld);
		}
	}
	
	
	class MyKL implements KeyListener{
		public void keyReleased(KeyEvent e)
		 {
			int code = e.getKeyCode();
			if (code == e.VK_ENTER){
				if (t1.getText().equals("")){return;}
				if(b.getHoehe()>max_hoehe){
					return;
				}
				else{
					System.out.println("Enter gedrückt!");
					zeichneSchluessel(Integer.parseInt(t1.getText()));
				}
			}
		 }
		public void keyPressed(KeyEvent e){}
		public void keyTyped(KeyEvent e){}
	}
}

Die main-Methode bzw. der Frame sind in dieser Datei BinBaumPanelRahmen.java


Code:
import javax.swing.*;
import java.awt.*;

/**
 * Panel zur Darstellung eines binären Suchbaums
 */

public class BinBaumPanelRahmen extends JFrame{
	
		
	public BinBaumPanelRahmen(String titel)
	{
		setTitle(titel);
		setSize(400, 500);
		setLocationRelativeTo(null);    
		getContentPane();
		BinBaumPanel binbp = new BinBaumPanel();
		add(binbp);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}
	public static void main(String[] args)
	{
		BinBaumPanelRahmen p = new BinBaumPanelRahmen("Binärer Suchbaum");
	}
}

Um das Programm auch "testen" zu können hier auch noch die Suchbaum-Datei
Code:
/** Ein abgeschlossener (encapsulation) Suchbaum
 * implementiert mit dem State- und Sigleton-Pattern.
 */
public class BinBaum_grafisch
{
  /** Die Wurzel Knoten
   * Ein Baum ist durch die Wurzel und seine Unterbäume (Kinder) definiert 
   * Für den leeren Baum ist die Wurzel durch den LeerenKnoten
   * repräsenteirt.
   */
  private AKnoten _wurzel;
  
  /** Erzeugt leerer Baum */
  public BinBaum_grafisch() {
    _wurzel = LeererKnoten.signleton();
  }
  
  /** Ist der Schlüssel im Baum (Suche) 
    * @param k Schlüssel
    */
  public boolean suchen(int k) {
    return _wurzel.suchen(k);
  }
  
  /** Fügt Schlüssel ein 
   * @param k Schlüssel
   */
  public void einfuegen(int k) {
    _wurzel.einfuegen(this, k);
  }
  
  /** Entfernt Schlüsel
   * @param k Schlüssel
   */
  public void entferne(int k) {
    _wurzel.entferne(this, k);
  }
  
  /** Ist Baum leer
   * @return true false leer
   */
  public boolean istLeer() {
    return _wurzel.istLeer();
  }
  
  /** Gibt den Baum in inorder aus. */
  public void printInOrder() {
    _wurzel.printInOrder();
  }
  
  /** gibt die jeweilige y-Koordinate zurück */
  public int getY(int s, int y_akt, int e_akt){
	  int y = y_akt;
	  int e = e_akt;
	  return _wurzel.getY(this, s, y, e);
  }
  
  /** gibt die jeweilige x-Koordinate zurück */
  public int getX(int s, int x_akt, int e_akt){
	  int x = x_akt;
	  int e = e_akt;
	  return _wurzel.getX(this, s, x, e);
  }
  
  /** errechnet die aktuelle Höhe des übergebenen
   * key
   */
  public int getHoehe(){
	  return _wurzel.getHoehe(this);
  }
  
  
  /** Entfernt grösster Schlüssel im Baum
   * wird für löschen(k) benötigt. Darf nur auf
   * nichtleerem Baum aufgerufen werden.
   * @return grösster Schlüssel im Baum
   */
  private int entferneGroesster() {
    return _wurzel.entferneGroesster(this);
  }
  
  /** Setzt Wurzel im Baum 
   * @k neue Wurzel
   */
  private void setzeWurzel(AKnoten k) {
    _wurzel = k;
  }
  
  /**
   * Gibt die Schrittweite auf der y-Achse zurück
   */
  public int getEbenenAbstand(){
  	return _wurzel.getEbenenAbstand();
  }
  
  /**
   * Gibt den Schlüssel des Vorgaengers zurück
   * @param s der Schlüssel, dessen Vorgänger gesucht wird
   * @param vor Platzhalter für Rückgabe
   * return den Vorgängerschlüssel
   */
  public int findeVorgaenger(int s, int vor){
	  return _wurzel.findeVorgaenger(this, s, vor);
  }
  
  /** Abstrakter Knoten
   * Suchbaum aggregiert diesen Knoten als Wurzel.
   * Die Abstrakte Klasse wird für das State-Pattern
   * verwendet.
   * State-Pattern ermöglicht eine einfache
   *  funktionsbezogene Implementierung.
   */
  static private abstract class AKnoten
  {
    /* Alle Operationen die auf den Knoten möglich sein sollen
      müssen hier definiert werden.
     */
    public abstract boolean suchen(int k);
    public abstract void einfuegen(BinBaum_grafisch b, int i);
    public abstract void entferne(BinBaum_grafisch b, int k);
    public abstract boolean istLeer();
    public abstract void printInOrder();
    public abstract int entferneGroesster(BinBaum_grafisch b);
    public abstract int getX (BinBaum_grafisch b, int s, int x, int e);
    public abstract int getY (BinBaum_grafisch b, int s, int y, int e);
    public abstract int getHoehe (BinBaum_grafisch b);
    public abstract int getEbenenAbstand();
    public abstract int findeVorgaenger(BinBaum_grafisch b, int s, int vor );
  }
  
  /** Leerer Knoten
   * Diese Klasse repräsentiert den leeren Knoten.
   * Singleton Klasse -> es gibt nur eine Instanz,
   * alle leeren Bäume sind gleich.
   * Implementiert alle Operationen auf dem leeren Baum.
   */
  static private class LeererKnoten extends AKnoten
  {
    
    public void einfuegen(BinBaum_grafisch b, int i) {
      b.setzeWurzel(new NichtLeererKnoten(i));
    }
    
    public boolean suchen(int k) {
      return false;
    }
    
    public void entferne(BinBaum_grafisch b, int k) {
      return;
    }
    
    public boolean istLeer() {
      return true;
    }
    
    public void printInOrder() {
      return;
    }
    
    /* nicht definiert auf leerem Knoten */
    public int entferneGroesster(BinBaum_grafisch b) {
      System.exit(0);
      //throw new Exception("Methode nicht definiert.");
      return 0;
    }
    
    public int getX(BinBaum_grafisch b, int s, int x_akt, int e_akt){	
    	return 500;   
    }
    
    public int getY(BinBaum_grafisch b, int s, int y_akt, int e_akt){	
    	return 500;   
    }
    
    public int getHoehe(BinBaum_grafisch b){
    	return 0;
    }
    
    public int getEbenenAbstand(){
    	return 0;
    }
    
    public int findeVorgaenger (BinBaum_grafisch b, int s, int vor){
    	return 0;
    }
    
    private static AKnoten _einmalig = null;
    
    public static AKnoten signleton() {
      if (_einmalig == null) {
        _einmalig = new LeererKnoten();
      }
      return _einmalig;
    }
  }
  
  /** NichtLeererKnoten
   * Zustand eines nicht leeren Knoten. Beinhaltet den
   * Schlüssel.
   * Implementiert alle Operationen auf einem Knoten
   */
  static private class NichtLeererKnoten extends AKnoten
  {
    // Felder
    /** Der linke Teilbaum */
    private BinBaum_grafisch _links;
    /** Der rechte Teilbaum */
    private BinBaum_grafisch _rechts;
    
    /** Der Schlüssel */
    private int _schluessel;
    
    /** Der Schlüssel */
    private int vorgaenger;
    
    /** die x-Position */
    private int x_Pos;
    
    /** die y-Position */
    private int y_Pos;
    
    /** die aktuelle Höhe */
    private int hoehe;
    
    /** die aktuelle Ebene */
    private int ebene;
    
    /** der Abstand der Ebenen */
    private int y_ebene;
    
    
    // Konstruktor
    public NichtLeererKnoten(int schluessel) {
      _schluessel = schluessel;
      _links = new BinBaum_grafisch();
      _rechts = new BinBaum_grafisch();
      vorgaenger = 0;
      x_Pos = 200;	// Startposition x;
      y_Pos = 20;	// Startposition y;
      hoehe = 0;	// Starthoehe;
      ebene = 1;	// Startebene;
      y_ebene = 40;	// Abstand der Ebenen;
      
    }
    
    // Operationen
    public void einfuegen(BinBaum_grafisch b, int i) {
      if (i < _schluessel) {
          _links.einfuegen(i);
      } else if (i > _schluessel){
          _rechts.einfuegen(i);
      } else { return; }
    }
    
    /**
     * Gibt den Vorgänger des übergebenen Schlüssels zurück
     * @param b der binäre Suchbaum
     * @param i der Schlüssel, dessen Vorgänger gesucht wird
     * @param v Platzhaltervariable für den Schlüssel des Vorgängers
     * @return vorgaenger der Schlüssel des Vorgängers
     */
    public int findeVorgaenger(BinBaum_grafisch b, int i, int vor) {
        if (i == _schluessel){
        	vorgaenger = vor;
        	return vorgaenger;
        }
    	if (i < _schluessel) {
    		vorgaenger = _schluessel;
            return _links.findeVorgaenger(i, vorgaenger);
        } else if (i > _schluessel){
            vorgaenger = _schluessel;
        	return _rechts.findeVorgaenger(i, vorgaenger);
        }
    	return vorgaenger;
      }
    
    public void entferne(BinBaum_grafisch b, int k) {
      if (k < _schluessel) { _links.entferne(k); }
      else if (k > _schluessel) { _rechts.entferne(k); }
      else {
        // Dieser Knoten muss entfernt werden
        if (_links.istLeer()) {
          b.setzeWurzel(_rechts._wurzel);
        } else if (_rechts.istLeer()) {
          b.setzeWurzel(_links._wurzel);
        } else {
          _schluessel = _links.entferneGroesster();
        }
      }
    }
    public boolean suchen(int k) {
      if (k == _schluessel) {
    	  //System.out.println("\nGefunden");
    	  return true; }
      if (k < _schluessel) { return _links.suchen(k); }
      else { return _rechts.suchen(k); }
    }
    
    public boolean istLeer() {
      return false;
    }
    
    public void printInOrder() {
      _links.printInOrder();
      System.out.print(_schluessel + " ");
      _rechts.printInOrder();
    }
    
    public int entferneGroesster(BinBaum_grafisch b) {
      if (_rechts.istLeer()) {
        b.setzeWurzel(_links._wurzel);
        return _schluessel;
      } else {
        return _links.entferneGroesster();
      }
    }
    
    /**
     * Gibt die Y-Koordinate des Punktes wieder, sofern der Punkt
     * enthalten ist. Ist der Schlüssel gefunden, wird der 
     * entsprechende Wert zurückgegeben, andernfalls 
     * wird rekursiv in den jeweiligen Unterbäumen weitergesucht. 
     * Diese Methode ließe sich auch in die Einfüge-Methode integrieren
     * doch aus Gründen der Übersichtlichkeit, sollen sie vorerst getrennt
     * bleiben. 
     * @param b der BinBaum
     * @param s der Schlüssel
     * @param y_akt der aktuelle Wert von y
     * @param e_akt die aktuelle Ebene
     */
    public int getY(BinBaum_grafisch b, int s, int y_akt, int e_akt){
    	boolean such = suchen(s);
    	y_Pos = y_akt;
    	//prev_Y = y_prev;
    	ebene = e_akt;
    	if (such){
    		if (s == _schluessel) {
    	      	return y_Pos; }
    	    if (s < _schluessel) {
    	        y_Pos+= 40;//y_ebene;
    	        return _links.getY(s, y_Pos, ebene); }
    	    else { 
    	    	y_Pos+= 40; //y_ebene;
    	        return _rechts.getY(s, y_Pos, ebene); }
    	}
    	return y_Pos;   
    }
    
    /**
     * Gibt die jeweilige Schrittweite, die dieser Ebene 
     * entspricht, zurück
     * @param e die Ebene, auf der sich der Knoten befindet
     * @return weite, die Schrittweite, um die der Knoten
     * versetzt werden muss. 
     */
    private int schrittWeiteBerechnen(int e){
    	e = ebene;
    	int weite=0;
    	switch(e){ 
    	case 1: weite=80;break;
    	case 2: weite=40;break;
    	case 3: weite=20;break;
    	case 4: weite=10;break;
    	}
    	return weite;
    }
    
    /**
     * Gibt den Abstand der Ebenen zurück
     * @return die Schrittweite auf der y-Achse;
     */
    public int getEbenenAbstand(){
    	return y_ebene;
    }
    
    /**
     * Ist der Schlüssel enthalten, so wird der entsprechende Wert
     * der x-Koordinate zurückgegeben. Dabei ist besonders zu
     * beachten, auf welcher Ebene gerade operiert wird, bzw.
     * ob es sich um den linken oder rechten Teilbaum handelt,
     * dementsprechend muss addiert bzw. subtrahiert werden. 
     * Diese Methode stützt sich ab auf die 
     * Methode schrittWeiteBerechnen(int e), die die jeweilige
     * Schrittweite berechnet.
     * @param b der BinBaum
     * @param s der Schlüssel
     * @param y_akt der aktuelle Wert von y
     * @param e_akt die aktuelle Ebene 
     */
    public int getX(BinBaum_grafisch b, int s, int x_akt, int e_akt){
    	boolean such = suchen(s);
    	x_Pos = x_akt;
    	//prev_X = x_prev;
    	ebene = e_akt;
    	if (such){
    		if (s == _schluessel) {
    	      	return x_Pos; }
    	    if (s < _schluessel) {
    	    	ebene+= 1;
    	    	int temp = schrittWeiteBerechnen(ebene);
    	    	x_Pos-= temp;
    	        return _links.getX(s, x_Pos, ebene); }
    	    else { 
    	        ebene+= 1;
    	        int temp = schrittWeiteBerechnen(ebene);
    	    	x_Pos+= temp;
    	        return _rechts.getX(s, x_Pos, ebene); 
    	    }
    	}
    	ebene+=1;
    	return x_Pos;   
    }
    
    /**
     * Gibt die Höhe des jeweiligen Baumknotens zurück.
     * (entspricht der jeweiligen Ebene)
     * @param b der BinBaum
     * @param s der Schlüssel
     * @param hoehe_akt die aktuelle Hoehe  
     */
    public int getHoehe(BinBaum_grafisch b){	
    	int hoehe_links = 1 + _links.getHoehe(); 
    	int hoehe_rechts = 1 + _rechts.getHoehe();
    	return (hoehe_links>hoehe_rechts)? hoehe_links : hoehe_rechts;
    }
  }
}
 
> Graphics g = getGraphics();

mit sowas kann alles nur schiefgehen,
rufe nie in deinem Leben getGraphics() aus, es sei denn du weißt genau was du tust,

die einzig erlaubte Art zu zeichnen ist

public void paintComponent (Graphics grafik)
{
super.paintComponents(grafik);
grafik.setColor(Color.lightGray);

// hier
}

von paintComponent kann man auch gerne Unteroperation aufrufen, grafik weiterreichen usw.

aber nie irgendwo das Graphics-Objekt speichern oder einfach mal mit getGraphics() außerhalb des normalen paint-Ablaufs aufrufen
 
wie aber soll das gehen? Ich möchte, dass zeichneSchluessel(int schluessel) erst dann aufgerufen wird, wenn entweder der EINGEBEN-Button oder die Enter-Taste gedrückt worden sind. zeichneSchluessel soll dann den Schlüssel an die richtige Stelle zeichnen. Ich weiß jetzt nicht, wie ich aus der Paint-Methode heraus auf den ActionListener zugreife, bzw. wie ich ohne Graphics-Objekt zeichnen soll.
 
> Ich weiß jetzt nicht, wie ich aus der Paint-Methode heraus auf den ActionListener zugreife, bzw. wie ich ohne Graphics-Objekt zeichnen soll.

weder das eine noch das andere musst du tun,
der ActionListener muss irgendeine Information in einer DatenKlasse oder unsauber direkt im JFrame/ JPanel ablegen,
a la 'Zeiche xy true/ false'
dann wird repaint() aufgerufen

und paintComponent zeichnet dann den aktuell korrekten Stand
 
Könntest du das bitte präzisieren, das verstehe ich so nicht.
 
siehe folgendes Beispiel:
der ActionListener hat nichts mit dem Zeichnen zu tun, außer dass er pauschal repaint() aufruft

das painten ist völlig unabhängig von irgendwelchen ActionListenern,
diese beiden Bereichen sollten nie etwas miteinander zu tun haben (außer repaint()-Aufruf)

dennoch wird nach jedem Button-Klick etwas anderes gemalt,
eben weil der ActionListener irgendeinen internen Zustand ändert
und das paint diesen Zustand berücksichtigt

Code:
public class TestGUI
    extends JFrame
{
    private int zahl = 5;

    public TestGUI()
        throws Exception
    {
        JButton b = new JButton("Test");
        b.addActionListener(new ActionListener()
            {

                public void actionPerformed(ActionEvent e)
                {
                    zahl++;
                    repaint();
                }
            });

        JPanel p = new JPanel()
            {
                public void paintComponent(Graphics g)
                {
                    super.paintComponent(g);
                    g.drawString("Zahl ist: " + zahl, 20, 20);
                }
            };
        add(p, BorderLayout.CENTER);
        add(b, BorderLayout.SOUTH);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 200);
        setVisible(true);
    }

    public static void main(String[] args)
        throws Exception
    {
        new TestGUI();
    }
}
 
war vorübergehend weg und konnte nicht gleich antworten. jetzt glaube ich geht mir ein Licht auf, ich werde das gleich einarbeiten.
vorerst danke vielmals.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben