Listeners anhalten

Stread

Mitglied
Hi,
ich möchte außerhalb der erstellten Java Gui Mausbewegungen und Klicks registrieren.
Mit dem JAR File von ksquared klappt das auch gut Java

Per Button auf meiner Gui starte ich die Erfassung. Nur das Problem ist, ich weiß nicht wie sie stoppen kann. Momentan läuft es ewig und mit
Java:
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wird alles beim beenden des Fensters einfach abgewürgt (?) Verbleibt dann nichts mehr "Schädliches" zurück?


Vorweg, der gesamte Code steht auch auf der Webseite, den betreffenden Teil habe ich kaum verändert.

Java:
	public static void mausk() {// wird bei Buttondruck ausgeführt
		new GlobalMouseListener().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent event) {
		// auszuführender code    }
			@Override
			public void mouseReleased(MouseEvent event) { }
			@Override
			public void mouseMoved(MouseEvent event) {
               //auszuführender code			}
		});

Genau so wie es einen .addMouseLisener gibt, habe ich auch einen .removeMouseListener entdeckt. Nun müsste es damit doch möglich sein den eben gesetzten Listener wieder zu entfernen? Erstelle ich einen neuen MouseListener mit new? Und wie übergebe ich ihm denn keinen new MouseAdapter sondern den schon verwendeten?



Hier noch die anderen Klassen, der Übersicht halber, es gibt noch mehr aber ich denke die sind nicht wichtig für mein Problem.

Java:
package MouseHook.src.MouseHook.de.ksquared.system.mouse;

import java.util.List;
import java.util.Vector;

public class GlobalMouseListener {
	protected PoolHook hook;
	public GlobalMouseListener() { (hook=new PoolHook(this)).start();	}
	protected List<MouseListener> listeners = new Vector<MouseListener>();

	public void addMouseListener(MouseListener listener) { listeners.add(listener); }
	public void removeMouseListener(MouseListener listener) { listeners.remove(listener); }

	void mouseMoved(MouseEvent event) {
		try {
			for(MouseListener listener:listeners)
				listener.mouseMoved(event);
		} catch(Exception e) { e.printStackTrace(); }
	}
	void mousePressed(MouseEvent event) {
		try {
			for(MouseListener listener:listeners)
				listener.mousePressed(event);
		} catch(Exception e) { e.printStackTrace(); }
	}
	void mouseReleased(MouseEvent event) {
		try {
			for(MouseListener listener:listeners)
				listener.mouseReleased(event);
		} catch(Exception e) { e.printStackTrace(); }
	}
}
Java:
package MouseHook.src.MouseHook.de.ksquared.system.mouse;

public class MouseAdapter implements MouseListener {
	@Override public void mouseMoved(MouseEvent event) {}
	@Override public void mousePressed(MouseEvent event) {}
	@Override public void mouseReleased(MouseEvent event) {}
}
Java:
package MouseHook.src.MouseHook.de.ksquared.system.mouse;

import java.util.EventListener;

public interface MouseListener extends EventListener {
	public void mouseMoved(MouseEvent event);
  public void mousePressed(MouseEvent event);
  public void mouseReleased(MouseEvent event);
}
 

Joose

Top Contributor
Genau so wie es einen .addMouseLisener gibt, habe ich auch einen .removeMouseListener entdeckt. Nun müsste es damit doch möglich sein den eben gesetzten Listener wieder zu entfernen?

Ja laut SourceCode wird dadurch der Listener wieder entfernt.

Erstelle ich einen neuen MouseListener mit new?

Objekte werden mit new instanziert. Das sind aber Java Basics!

Und wie übergebe ich ihm denn keinen new MouseAdapter sondern den schon verwendeten?

Indem du statt ein Objekt des gewünschten Listeners erstellst und dessen Referenz wo speicherst und erst dann den Listener hinzufügst. Dann kannst du später über die Referenz den Listener auf wieder entfernen.

Java:
	public static void mausk() {// wird bei Buttondruck ausgeführt
   ma = new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent event) {
		// auszuführender code    }
			@Override
			public void mouseReleased(MouseEvent event) { }
			@Override
			public void mouseMoved(MouseEvent event) {
               //auszuführender code			}
		};
		new GlobalMouseListener().addMouseListener(ma);
 
Zuletzt bearbeitet:

Stread

Mitglied
Danke, das hat funktioniert...glaube ich zumindest :)

Ist es besser den Listener immer manuell zu beenden?
Also sollte ich das
Java:
 static void unterbreche() {
		new GlobalMouseListener().removeMouseListener(ma);
	}
immer manuell aufrufen wenn ich die ganze Gui und damit das Programm beende?
Oder macht der GC genau das gleiche für mich?
Was ist besserer Stil?

PS. Das mit dem new habe ich anderst gemeint, aber egal ;)
 

Flown

Administrator
Mitarbeiter
Danke, das hat funktioniert...glaube ich zumindest :)

Ist es besser den Listener immer manuell zu beenden?
Also sollte ich das
Java:
 static void unterbreche() {
        new GlobalMouseListener().removeMouseListener(ma);
    }
immer manuell aufrufen wenn ich die ganze Gui und damit das Programm beende?
Oder macht der GC genau das gleiche für mich?
Was ist besserer Stil?

PS. Das mit dem new habe ich anderst gemeint, aber egal ;)

Du sollst deinen Listener von deiner Referenz entfernen und nicht einen neuen GlobalMouseListener erzeugen und dann von diesen löschen, weil dieser leer ist.

Warum machen sich eigentlich so viel sorgen was der GC macht? Java ist dazu gedacht, dass man sich eben keine Sorgen mehr um Speicherverwaltung machen muss (wenn man das will, dann nimmt man andere Sprachen/JVM die das können).

Wenn dein Programm nach schließen deines Frames beendet ist, dann gibt die JVM allen Speicher frei und gut ist.

Kurz gesagt, wenn das Frame sich schließt, dann wird die Referenz die in deinem Frameobjekt auf die Listener verweist nichtig und der GC kümmert sich darum.
 

Stread

Mitglied
Ich bin's nochmal

du hast recht, aber ich wüsste trotzdem gerne wie ich denn nun den Listener anhalten kann. Rein aus Interesse.

wenn ich das new weglasse meckert er dass GlobalMouseListener undefiniert ist für die Klasse
 

Stread

Mitglied
Bearbeiten geht anscheinend nicht mehr nach einer Zeit?

Der Grund warum ich das gerne manuell anhalten oder beenden würde ist folgender.

Wenn ich viel daran teste, das Programm oft aufrufe, kann es sein das der Listener nicht mehr funktioniert. Keine Fehlermeldung, nichts es passiert einfach nichts mehr. Ich kann das Programm beliebig oft ausführen. Erst nach einem kompletten Neustart des Rechners funktioniert wieder alles so wie es soll.
Warum ist das so? Nach schließen des Programms sollte die JVM doch alles mit ins Grab nehmen? Liegt es an den C++ libs die eingebunden werden?
 

kaoZ

Top Contributor
Mal abgesehen davon werden unter einem 32 Bit System sowieso maximal ~ 2048 MB an Speicher allokiert ( und auch nur wenn du die entsprechenden Parameter setzt )..... wenn du mehr Speicher verbrauchen würdest als deinem Heap / der JVM zu Verfügung steht fliegt eh eine OOM Exception....

Java:
Wenn ich viel daran teste, das Programm oft aufrufe, kann es sein das der Listener nicht mehr funktioniert. Keine Fehlermeldung, nichts es passiert einfach nichts mehr. Ich kann das Programm beliebig oft ausführen. Erst nach einem kompletten Neustart des Rechners funktioniert wieder alles so wie es soll. 
Warum ist das so?

ggf. ist die GC ja noch nicht mit dem entfernen der Referenzen durch....... vielleicht solltest du mal schauen ob irgendwo eine Exception fliegt, oder es ggf. probleme beim entfernen von irgendwelchen Referenzen oder ähnlichem gibt.
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben