# Mouse Listener beenden



## Paddel (20. Aug 2008)

Hallo ich habe eine Button der addet einen Mouselistener.
	
	
	
	





```
public class neuerZustand implements ActionListener{

		public void actionPerformed(ActionEvent arg0) {
		
		
			self.anzeige.addMouseListener(new MyMouseListener());
		
			
			
			
			
		}
		
	}
```
Dieser Mouse Listener erzeugt wenn er einmal gedrückt wird ein neues Fenster:
	
	
	
	





```
public void mousePressed(MouseEvent event) {
			final int x = event.getX();
			final int y = event.getY();

			namenEingeben.setSize(300, 150);
			namenEingeben.setLayout(null);

			namenEingebenLabel.setBounds(15, 0, 300, 30);
			namenEingebenArea.setBounds(15, 45, 10, 20);
			namenEingebenButton.setBounds(15, 85, 150, 30);

			namenEingeben.add(namenEingebenButton);
			namenEingeben.add(namenEingebenLabel);
			namenEingeben.add(namenEingebenArea);

			namenEingeben.setVisible(true);

			namenEingebenButton.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {

					Zustand zustand = new Zustand(self, namenEingebenArea.getText(), x, y);
				

				}

			});

		}

	}
```


Nun würde ich das aber gerne so haben das wenn ich ein einziges mal das Fenster erzeugt habe der Mouse Listener erneut aktiviert werden müsste über denn Button. Weil das ist nicht der Fall. Ebenfalls werden wenn ich dann ein neues Objekt mit einem neuem Namen erzeuge und dann noch eins die vorherigen auch in den neuen Namen umbenannt. Wäre nett wenn man mir ebend kurz helfen könnte.
Gruss


----------



## Wildcard (20. Aug 2008)

wo ein addMouseListener ist, gibt es auch ein removeMouseListener


----------



## Paddel (20. Aug 2008)

ok das klappt wunderbar. Nur passiert das immer noch das bei 

```
public void actionPerformed(ActionEvent arg0) {
					String text = namenEingebenArea.getText();
					Zustand zustand = new Zustand(self, text , x, y);
					namenEingeben.setVisible(false);
					self.anzeige.removeMouseListener(mouseListen);

				}
```
ich ein neues Objekt erzeuge. Wenn ich dann ein 2tes erzeuge dann ändert sich der alte name sprich der Text denn ich im Konstruktor übergebe in den alten Text. Obwohl ich das als final deklariert habe. Kann mir das nochmal jemand erklären.. das blick ich gar nicht. Hier nochmal der Konstruktor vom Zustand:

```
public Zustand(Automat automat,String name, int x, int y) {
		
		this.automat = automat;
		this.name = name;
		uebergaenge = new Uebergang[this.automat.getUebergaenge()];
		i = 0;
		automat.fuegeZustandHinzu(this);
		this.x = x;
		this.y = y;
	}
```


----------



## SlaterB (20. Aug 2008)

diese Problembeschreibung ist nicht gerade verständlich,
wer erzeugt wen wann warum?,
was ändert sich wo wie wann?

am besten mit vollständigen Programmcode und Beispielen/ Ablaufbeschreibung


----------



## Paddel (20. Aug 2008)

das ganze soll ein DEA Automat werden. Wir erzeugen hier einen neuen Zustand:

```
public class Zustand {
	Automat automat;
	Uebergang[] uebergaenge;
	final String name;
	int i;
	private int x, y;
	public Zustand(Automat automat,String name, int x, int y) {
		
		this.automat = automat;
		this.name = name;
		uebergaenge = new Uebergang[this.automat.getUebergaenge()];
		i = 0;
		automat.fuegeZustandHinzu(this);
		this.x = x;
		this.y = y;
	}
	public void uebergangHinzufuegen(Zustand zustand, String uebergang){
		for(int j=0;j < i;j++)
		{
			if(uebergaenge[j].getUebergang() == uebergang)
			{
				System.out.println("Übergang bereits vorhanden");
				return;
			}
			
		}
		this.uebergaenge[i] = new Uebergang(this, zustand,uebergang); 
		i++;
		
	}
	public boolean ready(){
		return i == automat.getUebergaenge();
	}
	public Zustand eingabe(String s){
		for(int j=0;j<i;j++){
			if(uebergaenge[j].getUebergang() == s)
			{
				if(uebergaenge[j].getZ1() != this)
					return uebergaenge[j].getZ1();
				else
					return uebergaenge[j].getZ2();
			}
		}
		return null;
	
	}

	
	public String getName() {
		// TODO Auto-generated method stub
		return name;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
		automat.anzeige.repaint();
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
		automat.anzeige.repaint();
	}
}
```

und das macht der Automat :
	
	
	
	





```
import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.Border;

import sun.java2d.Disposer;

public class Automat {
	String name;
	MyMouseListener mouseListen = new MyMouseListener();
	boolean neuerZustand = false;
	String[] Uebergaenge = { "a", "b" };
	Automat self = this;
	ArrayList<Zustand> zustaende = new ArrayList<Zustand>();
	Zustand start;
	Zustand aktuell;
	JFrame anzeige = new JFrame("DEA");
	Zeichenflaeche zeichenflaeche = new Zeichenflaeche();
	int i;
	JButton neuerZustandButton = new JButton("neuer Zustand");

	public Automat() {
		i = 0;
		anzeige.setSize(600, 600);
		anzeige.setLayout(null);

		anzeige.add(zeichenflaeche);
		anzeige.add(neuerZustandButton);

		zeichenflaeche.setBounds(0, 0, 500, 500);
		neuerZustandButton.setBounds(20, 500, 130, 30);
		neuerZustandButton.addActionListener(new neuerZustand());

		anzeige.setVisible(true);

		anzeige.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

	public void fuegeZustandHinzu(Zustand z) {
		if (start == null) {
			start = z;
			aktuell = z;
		}
		zustaende.add(z);
		i++;
		anzeige.repaint();

	}

	public void overwrite() {
		anzeige.repaint();
	}

	public void setUebergaenge(String[] übergänge) {
		Uebergaenge = Uebergaenge;
	}

	public void eingabe(String s) {
		aktuell = aktuell.eingabe(s);
		System.out.println("Neuer Zustand ist " + aktuell.getName());
	}

	// Innere Klassen
	class Zeichenflaeche extends JPanel {
		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);

			for (int j = 0; j < zustaende.size(); j++) {
				// if(!zustaende.isEmpty()){
				g.setColor(Color.BLACK);
				int x = zustaende.get(j).getX(), y = zustaende.get(j).getY(), gx = 30, gy = 30;
				g.fillOval(x, y, gx, gy);
				g.setColor(Color.WHITE);

				g.drawString(zustaende.get(j).getName(),
						(int) (x + (gx * 0.45)), (int) (y + (gy * 0.6)));
			}

		}
	}

	class MyMouseListener extends MouseAdapter {

		JFrame namenEingeben = new JFrame("...");
		JLabel namenEingebenLabel = new JLabel(
				"<html>Bitte geben sie den Namen\n des Zustandes ein

 (Bitte nur einen Buchstaben)</html>");
		JButton namenEingebenButton = new JButton("Zustand bennen");
		final JTextArea namenEingebenArea = new JTextArea();

		public void beenden() {
			namenEingeben.setVisible(false);

		}

		public void mousePressed(MouseEvent event) {
			final int x = event.getX();
			final int y = event.getY();

			namenEingeben.setSize(300, 150);
			namenEingeben.setLayout(null);

			namenEingebenLabel.setBounds(15, 0, 300, 30);
			namenEingebenArea.setBounds(15, 45, 10, 20);
			namenEingebenButton.setBounds(15, 85, 150, 30);

			namenEingeben.add(namenEingebenButton);
			namenEingeben.add(namenEingebenLabel);
			namenEingeben.add(namenEingebenArea);

			namenEingeben.setVisible(true);

			namenEingebenButton.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					String text = namenEingebenArea.getText();
					Zustand zustand = new Zustand(self, text , x, y);   <----- HIER WIRD EIN NEUER ZUSTAND ERZEUGT!!!!
					namenEingeben.setVisible(false);
					self.anzeige.removeMouseListener(mouseListen);

				}

			});

		}

	}

	public class neuerZustand implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {

			self.anzeige.addMouseListener(mouseListen);

		}

	}

	public int getUebergaenge() {
		return (int) zustaende.size();
	}
}
```

Wenn ich dann irgendwo hinklicke öffnet sich das neue Fenster wo ich dann einen Buchstaben eingeben kann, und ein neuer Zustand wird in der ArrayList Zustände in Automat geaddet. Self ist in diesem Fall der Automat selber denn ich als Variable abgespichert habe. Text ist der Name der angezeigt wird und x und y die Koordinaten wo der Zustand dann erscheint. Das klappt auch wunderbar. Nur erzeuge ich dann einen 2ten Zustand wird der Name im alten Zustand ebenfalls in denn neuen geändert. Allerdings nur wenn ich das so mache. Wenn ich :
	
	
	
	





```
public static void main(String[] args) {
		
	
	Automat automat = new Automat();
	Zustand a = new Zustand(automat, "a", 0, 0);

	Zustand b = new Zustand(automat, "b",40,40);

	Zustand c = new Zustand(automat, "c",80,80);
	Zustand d = new Zustand(automat, "d",160,160);
```
 das auf diese Art mache klappt das perfekt. Ich verstehe nicht wie es dann möglich ist das er denn Namen der sowieso als final deklariert ist geändert werden kann geändert werden kann.
Das passiert dann in :
	
	
	
	





```
class MyMouseListener extends MouseAdapter {

		JFrame namenEingeben = new JFrame("...");
		JLabel namenEingebenLabel = new JLabel(
				"<html>Bitte geben sie den Namen\n des Zustandes ein

 (Bitte nur einen Buchstaben)</html>");
		JButton namenEingebenButton = new JButton("Zustand bennen");
		final JTextArea namenEingebenArea = new JTextArea();

		public void beenden() {
			namenEingeben.setVisible(false);

		}

		public void mousePressed(MouseEvent event) {
			final int x = event.getX();
			final int y = event.getY();

			namenEingeben.setSize(300, 150);
			namenEingeben.setLayout(null);

			namenEingebenLabel.setBounds(15, 0, 300, 30);
			namenEingebenArea.setBounds(15, 45, 10, 20);
			namenEingebenButton.setBounds(15, 85, 150, 30);

			namenEingeben.add(namenEingebenButton);
			namenEingeben.add(namenEingebenLabel);
			namenEingeben.add(namenEingebenArea);

			namenEingeben.setVisible(true);

			namenEingebenButton.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					String text = namenEingebenArea.getText();
					Zustand zustand = new Zustand(self, text , x, y);   <----- HIER WIRD EIN NEUER ZUSTAND ERZEUGT!!!!
					namenEingeben.setVisible(false);
					self.anzeige.removeMouseListener(mouseListen);

				}

			});

		}

	}
```
 Ich habe das Objekt aber schon erzeugt. Und die x und y Koordinaten ändern sich auch nicht. Aber der Name. Hoffe das ist jetzt verständlich...


----------



## SlaterB (20. Aug 2008)

> String text = namenEingebenArea.getText(); 

in der actionPerformed wird erst zum Zeitpunkt des Button-Klicks text bestimmt,
im Gegensatz zu x und y kann text also unterschiedliche Werte annehmen in unterschiedlichen Zuständen,
da ist auch nix final,

wenn du aber einen Zustand erzeugt hast, ist darin text final abgelegt
und kann nicht verändert werden,


----------



## Paddel (20. Aug 2008)

sry wenn ich jetzt etwas rumnerve aber auch nach 3 mal lesen versteh ich dich nich so ganz. Kannst mit malen Beispiel dazu geben?


----------



## SlaterB (20. Aug 2008)

wenn in namenEingebenArea 'X' steht und namenEingebenButton geklickt wird,
wird ein Zustand 1 mit text = 'X' erzeugt

wenn nach in namenEingebenArea 'Y' geschrieben wird und wieder der Button drankommt,
so erzeugt der Listener einen neuen Zustand 2 mit 'Y'

Zustand 1 behält aber seinen Namen 'X'

das ist das derzeitige Verhalten, keine Ahnung ob das was deinem Problem zu tun hat


----------



## Paddel (20. Aug 2008)

hmmm..anders gefragt. Hättest du ne Lösung wie ich das Problem umgehen könnte?


----------



## SlaterB (20. Aug 2008)

ich weiß noch nichtmal was dein Problem ist..


----------



## Paddel (22. Aug 2008)

Sry das ich erst so spät zurückschreibe. Aber hatte Fieber und lag im Bett
img3.imagebanana.com/view/ls9s4o9g/Bild1.JPG

Hier habe ich das Problem glaube ich ganu gut beschrieben mit ein paar Grafiken. Wäre super wenn du da ma rüber schauen könntest. Denke das ist jetzt verständlich gemacht.
Gruss


----------



## SlaterB (22. Aug 2008)

vertracke Sache, liegt an deinem schlimmen schlimmen Programmaufbau,

also:
jedesmal wenn mousePressed() in MyMouseListener ausgeführt wird,
erhält der namenEingebenButton einen neuen ActionListener, der alte wird aber nicht entfernt,

am Anfang wird ein a-Punkt erstellt, beim nächsten Mal zwei b-Punkte,
einen an der neuen und einem an der alten Posititon, da zwei ActionListener auf den Button-Klick reagieren,
der Automat hat dann gleich 3 Punkte und a wird verdeckt

-------

hab dein Programm mal bisschen verbessert, aber da ist noch viel viel zu tun,
allen voran: Zustand sollte nicht Automat kennen!


```
public class Automat
{
    String name;
    MyMouseListener mouseListen = new MyMouseListener();
    boolean neuerZustand = false;
    String[] Uebergaenge =
        {"a", "b"};
    ArrayList<Zustand> zustaende = new ArrayList<Zustand>();
    Zustand start;
    Zustand aktuell;
    JFrame anzeige = new JFrame("DEA");
    Zeichenflaeche zeichenflaeche = new Zeichenflaeche();
    JButton neuerZustandButton = new JButton("neuer Zustand");

    public Automat()
    {
        anzeige.setSize(600, 600);
        anzeige.setLayout(null);

        anzeige.add(zeichenflaeche);
        anzeige.add(neuerZustandButton);

        zeichenflaeche.setBounds(0, 0, 500, 500);
        neuerZustandButton.setBounds(20, 500, 130, 30);
        neuerZustandButton.addActionListener(new neuerZustand());

        anzeige.setVisible(true);

        anzeige.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    public void fuegeZustandHinzu(Zustand z)
    {
        if (start == null)
        {
            start = z;
            aktuell = z;
        }
        zustaende.add(z);
        anzeige.repaint();

    }

    class Zeichenflaeche
        extends JPanel
    {
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            System.out.println("paint");
            for (int j = 0; j < zustaende.size(); j++)
            {
                // if(!zustaende.isEmpty()){
                g.setColor(Color.BLACK);
                int x = zustaende.get(j).getX(), y = zustaende.get(j).getY(), gx = 30, gy = 30;
                g.fillOval(x, y, gx, gy);
                g.setColor(Color.WHITE);

                g.drawString(zustaende.get(j).getName(), (int)(x + (gx * 0.45)), (int)(y + (gy * 0.6)));
                System.out.println("j: " + zustaende.get(j).getName());
            }

        }
    }

    class MyMouseListener
        extends MouseAdapter
    {

        JFrame namenEingeben = new JFrame("...");
        JLabel namenEingebenLabel = new JLabel(
                                               "<html>Bitte geben sie den Namen\n des Zustandes ein

 (Bitte nur einen Buchstaben)</html>");
        JButton namenEingebenButton = new JButton("Zustand bennen");
        final JTextArea namenEingebenArea = new JTextArea();
        private int x;
        private int y;

        public MyMouseListener()
        {
            namenEingeben.setSize(300, 150);
            namenEingeben.setLayout(null);

            namenEingebenLabel.setBounds(15, 0, 300, 30);
            namenEingebenArea.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            namenEingebenArea.setBounds(15, 45, 20, 20);
            namenEingebenButton.setBounds(15, 85, 150, 30);

            namenEingeben.add(namenEingebenButton);
            namenEingeben.add(namenEingebenLabel);
            namenEingeben.add(namenEingebenArea);
            namenEingeben.setVisible(false);

            namenEingebenButton.addActionListener(new ActionListener()
                {

                    public void actionPerformed(ActionEvent arg0)
                    {
                        String text = namenEingebenArea.getText();
                        Zustand zustand = new Zustand(text, x, y);
                        Automat.this.fuegeZustandHinzu(zustand);
                        namenEingeben.setVisible(false);
                        Automat.this.anzeige.removeMouseListener(mouseListen);
                    }

                });
        }

        public void mousePressed(MouseEvent event)
        {
            this.x = event.getX();
            this.y = event.getY();
            namenEingebenArea.setText("");
            namenEingeben.setVisible(true);

        }
    }

    public class neuerZustand
        implements ActionListener
    {

        public void actionPerformed(ActionEvent arg0)
        {

            Automat.this.anzeige.addMouseListener(mouseListen);

        }
    }

    public static void main(String[] args)
    {
        new Automat();
    }
}


class Uebergang
{
    String uebergang;
    Zustand z1;
    Zustand z2;

    /**
     * @param uebergang
     * @param z1
     * @param z2
     */
    public Uebergang(Zustand z1, Zustand z2, String uebergang)
    {
        this.uebergang = uebergang;
        this.z1 = z1;
        this.z2 = z2;
    }

    /**
     * @return uebergang
     */
    public String getUebergang()
    {
        return this.uebergang;
    }

    /**
     * @return z1
     */
    public Zustand getZ1()
    {
        return this.z1;
    }

    /**
     * @return z2
     */
    public Zustand getZ2()
    {
        return this.z2;
    }

}


class Zustand
{
    Uebergang[] uebergaenge;
    final String name;
    int i;
    private int x, y;

    public Zustand(String name, int x, int y)
    {
        System.out.println("new Z: " + name + ", " + Helper.getFilteredCallers(7));
        this.name = name;
        uebergaenge = new Uebergang[1];
        i = 0;
        this.x = x;
        this.y = y;
    }

    public void uebergangHinzufuegen(Zustand zustand, String uebergang)
    {
        for (int j = 0; j < i; j++)
        {
            if (uebergaenge[j].getUebergang() == uebergang)
            {
                System.out.println("Übergang bereits vorhanden");
                return;
            }

        }
        this.uebergaenge[i] = new Uebergang(this, zustand, uebergang);
        i++;
    }


    public String getName()
    {
        return name;
    }

    public int getY()
    {
        return y;
    }

    public void setY(int y)
    {
        this.y = y;
    }

    public int getX()
    {
        return x;
    }

    public void setX(int x)
    {
        this.x = x;
    }
}
```


----------



## Paddel (23. Aug 2008)

erstmal vielen Dank!


----------



## Paddel (23. Aug 2008)

wieso soll der Zustand seinen Automat nicht kennen? Was bringt das für einen Vorteil mit sich. Bin ja gerne bereit deine Tipps anzunehmen da du sicherlich mehr Plan von der Materie hast  aber wenn du mir dann auch noch erklärst wieso dann kann ich das die nächsten male selber anwenden 
Gruss


----------



## SlaterB (23. Aug 2008)

ein Zustand ist ein kleiner dummer Baustein in deinem Programm und sollte höchstens sich selber + vielleicht noch paar Kanten überblicken,
wenn jeder jeden kennt ist das alles unnötig kompliziert ineinander verwrungen,
z.B.
> automat.fuegeZustandHinzu(this); 

ist Unfug, genausogut kann der Aufrufer, der den Automat kennt,
automat.fuegeZustandHinzu(neuerZustand); 
aufrufen, siehe meinen Code,

wozu du den Automat sonst noch brauchst weiß ich nicht so genau,
aber was immer du einen Zustand fragen willst,
so wie public boolean ready(),
sollte allein diesen Zustand betreffen, warum muss der Zustand da beim Automat nachfragen?
wer ruft denn ready() von Zustand auf? entweder der Automat oder eine andere höhere Komponente und die kann dann genausogut selber beim Automat irgendwas abfragen

allgemeiner Grundsatz: möglichst wenig vernetzte Kenntnisse, insbesondere sollten die kleinen Nummern nicht unbedingt die großen kennen müssen,

nicht immer machbar aber doch anzustreben,
Beispiele:
AcktionListener kennt oft Button nicht, TableModel nicht die Table,
Elemente nicht die ArrayList, in der sie enthalten sind (können auch in mehren Listen enthalten sein)


----------

