Hallo,
ich wollte mir eben eine Art "Vektorfeld" erzeugen in dem irgendwelche Punkte, Linien (wie auch immer) der Maus folgen, d.h. in deren Richtung zeigen oder sie "umzingeln". Um das konkrete Aussehen soll es hier nicht gehen, deswegen nicht weiter präzisiert...
Da kam in mir die Frage auf, wie man sowas mit dem MouseMotionListener üblicherweise realisiert. Das Feld soll ja neu gezeichnet werden sobald sich die Maus bewegt.
Da allerdings im Gegensatz zu bestimmten Aktionen wie neuskalierung etc. eine Mausbewegung ja nicht automatisch repaint() aufruft war mein erster Ansatz in der main()-Methode repaint in einer Dauerschleife auszuführen und sich in der paintComponent-Methode jedes Mal die Mausposition zu besorgen. Das funktioniert auch aber erscheint mir in vielerlei Hinsicht als sehr unelegante Lösung.
Eine Idee wäre hier in einer Dauerschleife die Mausposition abzufragen und repaint aufzurufen, wenn sich die Mausposition im Vergleich zu ihrer vorherigen Position verändert hat. Ist das der normale Weg für so etwas, oder geht man hier normalerweise ganz anders vor?
Also meine Idee:
Zugegeben, auch das halte ich für vollkommen unelegant, da die mouseMoved Methode ja eigentlich genau das aufzeigt, da muss ich ja nicht nochmal prüfen ob die position eine neue ist... Allerdings wollte ich noch ein boolean flag erzeugen, mit dem ich von außen abfragen kann ob sich was getan hat.
Der Übersichtlichkeit wegen habe ich jetzt die Klasse DetectionPanel, abgeleitet von JPanel weggelassen. Hier wird einfach ein Panel erzeugt, an diesem der Positiondetector (Typ MouseMotionlistener) angemeldet und die paintComponent(Graphics g) Methode definiert, die einfach abhängig von der Mausposition Elemente einzeichnet.
Mit der (denke ich) uneleganten Lösung (repaint() in Dauerschleife) funktioniert es im Prinzip auch, diese zweite Lösung hier funktioniert nicht und ich verstehe gar nicht warum.
In der Konsole wird mir angezeigt wenn ich die Maus bewege, wenn ich das Fenster neu skaliere, dann wird auch neu gezeichnet. Wenn ich aber die positionChanged Variable auslese und dann manuell repaint() aufrufe funktioniert es nicht... Kann mir jemand sagen warum es nicht funktioniert? Und außerdem wie man so ein Szenario üblicherweise realisiert, ohne dass sich einem Java Entwickler die Nackenhaare aufstellen?
ich wollte mir eben eine Art "Vektorfeld" erzeugen in dem irgendwelche Punkte, Linien (wie auch immer) der Maus folgen, d.h. in deren Richtung zeigen oder sie "umzingeln". Um das konkrete Aussehen soll es hier nicht gehen, deswegen nicht weiter präzisiert...
Da kam in mir die Frage auf, wie man sowas mit dem MouseMotionListener üblicherweise realisiert. Das Feld soll ja neu gezeichnet werden sobald sich die Maus bewegt.
Da allerdings im Gegensatz zu bestimmten Aktionen wie neuskalierung etc. eine Mausbewegung ja nicht automatisch repaint() aufruft war mein erster Ansatz in der main()-Methode repaint in einer Dauerschleife auszuführen und sich in der paintComponent-Methode jedes Mal die Mausposition zu besorgen. Das funktioniert auch aber erscheint mir in vielerlei Hinsicht als sehr unelegante Lösung.
Eine Idee wäre hier in einer Dauerschleife die Mausposition abzufragen und repaint aufzurufen, wenn sich die Mausposition im Vergleich zu ihrer vorherigen Position verändert hat. Ist das der normale Weg für so etwas, oder geht man hier normalerweise ganz anders vor?
Also meine Idee:
Java:
public class PositionDetector implements MouseMotionListener {
int x, y, xOld, yOld;
boolean positionChanged;
@Override
public void mouseMoved(MouseEvent e) {
this.x = e.getX();
this.y = e.getY();
if (this.xOld != x || this.yOld != y) {
this.positionChanged = true;
System.out.println("Position changed");
this.xOld = x;
this.yOld = y;
} else {
positionChanged = false;
System.out.println("---");
}
}
Zugegeben, auch das halte ich für vollkommen unelegant, da die mouseMoved Methode ja eigentlich genau das aufzeigt, da muss ich ja nicht nochmal prüfen ob die position eine neue ist... Allerdings wollte ich noch ein boolean flag erzeugen, mit dem ich von außen abfragen kann ob sich was getan hat.
Java:
public class MouseDetectionTest {
public static void main(String[] args) {
DetectionPanel detectionPanel = new DetectionPanel();
JFrame f = new JFrame("Fenster");
f.setLayout(new GridLayout(2, 2));
f.add(detectionPanel);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocation(200, 200);
f.setSize(300, 300);
f.setVisible(true);
while (true) {
if (detectionPanel.positionDetector.positionChanged == true) {
detectionPanel.repaint();
}
}
}
}
Der Übersichtlichkeit wegen habe ich jetzt die Klasse DetectionPanel, abgeleitet von JPanel weggelassen. Hier wird einfach ein Panel erzeugt, an diesem der Positiondetector (Typ MouseMotionlistener) angemeldet und die paintComponent(Graphics g) Methode definiert, die einfach abhängig von der Mausposition Elemente einzeichnet.
Mit der (denke ich) uneleganten Lösung (repaint() in Dauerschleife) funktioniert es im Prinzip auch, diese zweite Lösung hier funktioniert nicht und ich verstehe gar nicht warum.
In der Konsole wird mir angezeigt wenn ich die Maus bewege, wenn ich das Fenster neu skaliere, dann wird auch neu gezeichnet. Wenn ich aber die positionChanged Variable auslese und dann manuell repaint() aufrufe funktioniert es nicht... Kann mir jemand sagen warum es nicht funktioniert? Und außerdem wie man so ein Szenario üblicherweise realisiert, ohne dass sich einem Java Entwickler die Nackenhaare aufstellen?