AWT Mausbarriere Maus fangen

CodeKrieger

Mitglied
Hallo,
ich möchte ein Fenster machen, aus dem die Maus nicht mehr rauskommt (bis man eine Tastenkombination drückt).

Dazu habe ich diese Funktion hier

Java:
public void mouseExited(MouseEvent evt) {
    if(mouseTrapped){
        try {
            Robot robot = new Robot();                             
            
            robot.mouseMove(evt.getXOnScreen(), evt.getYOnScreen());
            System.out.println("XY Screen "+evt.getXOnScreen() +" "+ evt.getYOnScreen());
            
            
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

Leider klappts ned :( Wenn ich in die Funktion MouseMove(0, 0) einsetzt, dann springt die Maus auch sichtbar dorthin. Nur mit getXOnScreen() klappt es nicht, weder bei schneller noch bei langsamer Bewegung. Es ist einfach kein Unterschied zur normalen Bewegung spürbar.

Schreibe ich dagegen getX(), so springt die Maus an die falsche Stelle (logischerweise).

Hat jemand eine Idee, wie ich das umsetzen kann? Ich vermute irgendwas ist hier zu träge?
 

Marco13

Top Contributor
Hm... "Wenn die Maus sich rausbewegt hat, soll sie sich da hin bewegen, wo sie ist" (modulo Details dazu, was im MouseEvent genau steht). Reicht's nicht die Maus immer in die Fenstermitte zu setzen (und ggf. den Cursor zu verstecken) ? Da war neulich ein Thread dazu...
 
S

SlaterB

Gast
was ist denn dein Ziel mit getXOnScreen() ?
wenn die Maus exakt dort schon ist, was sonst sollte getXOnScreen() auch sein, dann bringt es doch nichts, dorthin, also zu exakt derselben Position, zu springen?

du könntest zu einer bestimmten festen Position in der Mitte der Falle springen,
oder du merkst dir versetzt die vorherige Position, vom letzten Event, per mouseMoved bekommst du vielleicht alle mit

Tipp für diesen Fall:
bei schneller Maus-Bewegung werden evtl. mehrere Pixel übersprungen,
dann berechne falls gewünscht auf der Linie zwischem letzten und neuen Punkt den Punkt, der genau an der Grenze liegt
 

CodeKrieger

Mitglied
Ihr kennt doch alle VirtualBox. Hat man da keine GuestAdditions installiert, muss man die Maus umschalten. Genau so soll das bei mir auch sein. Die Maus darf unter keinen Umständen "springen", da die Mausbewegungen aufgezeichnet und später abgespielt werden. Aus Gründen der Usability und der Zuverlässigkeit der Aufzeichnungen soll verhindert werden, dass die Maus während das Aufzeichnung aus dem Fenster herausbewegt wird.

Ja, so wie Slater das sagt habe ich mir das auch schon vorgestellt. Nur wie könnte mans noch realisieren?

getXOnScreen() funktioniert also eigentlich, nur dass die Maus trotzdem über den Rand springt, weil das Event mouseExited() nur einmal ausgelöst wird... bzw. selbst bei langsamer Bewegung (davon kann man hier ausgehen) ist die Maus schneller draussen als dann wieder mouseExited() ausgelöst wird.

Edit: getXOnScreen() - 5 funktioniert zufriedenstellend - aber halt nur rechts und unten. Links und oben geht das in die Hose. Und bei schneller Bewegung springt die Maus trotzdem drüber. Das ist also nicht so zuverlässig. Über eine Alternative wäre ich sehr dankbar.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Die Maus springt "immer": Wenn man die Maus von 0,0 nach 10,0 bewegt, werden ja nicht 10 MouseEvents gefeuert. Ich denke, das, was SlaterB vorgeschlagen hat, wäre hier der beste Trade-Off, also immer bei MouseMoved/Dragged die Position speichern, und bei einem MouseExited auf die letzte "gültige" Position zurückspringen.
 

CodeKrieger

Mitglied
Das funktioniert absolut super, danke!

Code
Java:
private Point lastPosition = new Point();

public void mouseExited(MouseEvent evt) {
    if(mouseTrapped){
        try {
            Robot robot = new Robot();   
            
            
            robot.mouseMove((int)lastPosition.getX(), (int)lastPosition.getY());
            
            System.out.println("XY Screen "+evt.getXOnScreen() +" "+ evt.getYOnScreen());
            
            
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    }

public void mouseMoved(MouseEvent evt) {
    if (!inputBlocked){
        processLocalMouseEvent(evt, true);
        lastPosition.x = evt.getXOnScreen();
        lastPosition.y = evt.getYOnScreen();
    }
}
 

CodeKrieger

Mitglied
So, jetzt habe ich noch ein ähnliches Problem, zu dem vielleicht auch einer von euch eine schnelle Lösung hat. Sonst müsste ich da ewig herumprobieren.

Wie ich schon im anderen Thread beschrieben habe, soll es einen UserInteractionMode geben, in dem der Benutzer während der Wiedergabe der Aufzeichnung (Mausbewegungen+Tastatur) auch Eingaben vornehmen kann. Dadurch kann er aber auch die Maus verschieben, was zur Folge hat, dass die Aufzeichnungen dann danach nicht mehr gehen. Deshalb muss die Mausposition zurückgesetzt werden. Dazu habe ich folgende zwei Methoden geschrieben

Java:
//called when leaving UserInteractionMode
public void correctMousePos(){   
      if(this.isFocusOwner() && (lastX != saveX || lastY != saveY)){
          try{
              Robot robot = new Robot(); 
              robot.mouseMove(saveX, saveY);
          }
          catch(AWTException e){
              e.printStackTrace();
          }
          System.out.println("Mouse Position corrected");
          
      
      }
      
  }
  //This method is called when entering user interaction mode
  public void saveMousePos(){
      saveX = lastX;
      saveY = lastY;
  }

Das Problem ist jetzt: Die Maus bewegt sich viel zu schnell. In dem Canvas-Fenster wird ein altes Betriebssystem wie Windoof 3.11 oder 9x emuliert. Diese alten Systeme haben ihren eigenen Mauszeiger, der jedoch nur dann deckungsgleich ist, wenn man die Maus gaaaaanz langsam bewegt. Es muss da also irgendwie ein Delay rein, meine bisherigen Versuche waren allerdings wenig erfolgreich.

Und noch eine Frage: Wie kann ich erreichen, dass das ganze überhaupt nur dann funzt, wenn das Fenster im Vordergrund ist. Denn beim Debuggen ist es sehr nervig, wenn die Maus an einer Position festhängt, obwohl das Netbeans-Fenster offen ist und nicht das Java-Fenster. Das isFocusOwner scheint nicht ganz zu klappen.
 

CodeKrieger

Mitglied
Sobald ich hier eine While-Schleife mit der Bedingung

lastX != saveX || lastY != saveY

reinmache, gibt es eine Endlosschleife und die Maus geht immer wieder zu dem Punkt, auch wenn ich das Fenster schließe. Die Bedingung wird offenbar nie nicht erfüllt. Woran könnte das liegen?
 
S

SlaterB

Gast
wie soll man aus dem Code irgendwas erkennen?
wer ruft wann je saveMousePos() auf, genauso correctMousePos(),
was kann das mit Geschwindigkeiten zu tun haben,
inwiefern sind Simulationen beteiligt, doppelte Verarbeitung der Maus-Positionen vielleicht,
was interessiert deinen Code wie langsam Win95 ist oder muss das Informationen an dein Programm weiterreichen usw.

tausende Fragen ohne überhaupt ein Anfang oder Ende in Sicht

glaube nicht dass hier solche komplexen Dinge besprochen werden können,
aber das auch nur um überhaupt noch mal zu antworten
 

CodeKrieger

Mitglied
Ja sorry, eine Masterarbeit ist nunmal leider nicht so ganz einfach :)

SaveMousePos wird aufgerufen, wenn in den UserInteractiveMode gewechselt wird. An diese Stelle soll die Maus nachher zurückbewegt werden.

correctMousePos() wird daher aufgerufen, bevor man aus diesem Modus zurückkehrt in den normalen Modus.

Es werden hier alte Betriebssysteme emuliert, die die Mauspositionen total anders verarbeiten. Es gibt also zwei Mauszeiger, den von Java bzw. Ubnuntu wo ich arbeite und den von Windows 3.x. Den von Java kann man natürlich ausblenden, wie ihr das von VirtualBox kennt. Windows 3.x ist in dieser Hinsicht noch erheblich besser als 9x, die Maus lässt sich relativ schnell schieben ohne, dass man den Mauszeiger von Win "überholt". In Win 9x muss man schon sehr vorsichtig sein, die Maus ist hier sehr empfindlich und verliert leicht ihre Synchronisation.

Man kann das vielleicht am besten mit Billiard vergleichen. Hat mein Mauszeiger (Ubuntu) zu großen Impuls, so springt der emulierte Zeiger. Der Ubuntu-Zeiger, der ja von Java hier bewegt werden soll, muss sich also entsprechend einfühlsam und langsam bewegen.

Hier mein aktueller Code. Ich habe ein weniger herumexperimentiert. delay scheint absolut nicht zu klappen. Bei delay=1000 und stepSize = 1 müsste der ja bei jedem Pixel Bewegung eine Sekunde warten. Tut er aber nich.

Java:
public void correctMousePos(){   
      if(this.isFocusOwner() && (lastX != saveX || lastY != saveY)){
          try{
              Robot robot = new Robot();  
              int stepSize = 20;
              int delay = 1000;
              //larger steps
              for (int i = lastX; i <= saveX - stepSize; i += (int)Math.signum(saveX - lastX)*stepSize){
                  for (int j = lastY; j <= saveY - stepSize; j += (int)Math.signum(saveY - lastY)*stepSize){
                      robot.mouseMove(i, j);
                      robot.delay(delay);
                  }
              }
              //the last few pixels
              for (int i = lastX; i <= saveX; i++){
                  for (int j = lastY; j <= saveY; j++){
                      robot.mouseMove(i, j);
                      robot.delay(delay);
                  }
              }
              
              
          }
          catch(AWTException e){
              e.printStackTrace();
          }
          System.out.println("Mouse Position corrected");
          
      
      }

Die ganze Frage ist eigentlich: Kennt ihr eine Möglichkeit, die Maus (mit oder ohne Robot) langsam statt sprunghaft zu bewegen? Die Bewegung sollte eben so sein wie ein Mensch (mein Opa) das machen würde.

Hier mal ein Bild

Bei saveMousePos() sind beide Zeiger über dem P von Programm-Manager. Dann beginnt der UI-Modus, ich bewege den Zeiger langsam nach rechts bis zu dem Schriftzug. Nun beende ich den UIMode und der Zeiger springt zurück. Dabei stößt er den emulierten Zeiger vor sich her.
 
Zuletzt bearbeitet:

CodeKrieger

Mitglied
Edit, ich habe was falsch gemacht. So wie der Code jetzt ist, geht er in die Schleifen garnicht rein, daher bewegt sich der Mauszeiger garnicht. Vorher war oberhalb der Schleifen noch eine Zeile robot.mouseMove(lastX, lastY), daher kam dann die sprunghafte Bewegung.

Die Frage ist nun also warum er nicht da reingeht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Linie mit der Maus auswählen AWT, Swing, JavaFX & SWT 5
B mit maus Objekt bewegen AWT, Swing, JavaFX & SWT 3
R Swing Panel nur bei Maus sichtbar AWT, Swing, JavaFX & SWT 2
B mit Maus verschiebbares Panel AWT, Swing, JavaFX & SWT 2
C JTextField Inhalt mit Maus selektieren wenn disabled AWT, Swing, JavaFX & SWT 2
S JavaFX Fenster aufkommen lassen, wenn mit der Maus über bestimmten Bereich fahren AWT, Swing, JavaFX & SWT 1
F Event wenn Maus eine JList verlässt AWT, Swing, JavaFX & SWT 13
T Timer und GIF Animationen pausieren während Maus sich bewegt AWT, Swing, JavaFX & SWT 4
M Bild in JPanel mit Maus einfügen AWT, Swing, JavaFX & SWT 0
B Swing Form undecorated: Beim Bewegen geht die Maus immer automatisch zur linken Seite. AWT, Swing, JavaFX & SWT 7
L 2D-Grafik Bild in Richtung Maus drehen AWT, Swing, JavaFX & SWT 18
K Swing Maus in Panel einsperren AWT, Swing, JavaFX & SWT 8
D Swing JList keine Selektionsänderung bei "dragged-Maus" AWT, Swing, JavaFX & SWT 4
A JFrame Größenänderung mit Maus und GridLayout AWT, Swing, JavaFX & SWT 10
J Maus "locken" für Menü AWT, Swing, JavaFX & SWT 8
D Grafiken an Maus anhängen AWT, Swing, JavaFX & SWT 2
P Pfeilpolygon per Maus rotierbar machen - Kleine Schwierigkeiten AWT, Swing, JavaFX & SWT 29
P Event Handling Gedrückte Maus Blockiert MausEvents AWT, Swing, JavaFX & SWT 2
R Swing Per Maus JLabel resizen AWT, Swing, JavaFX & SWT 6
F Maus von alleine bewegen! AWT, Swing, JavaFX & SWT 8
G Swing JPanel per Maus verschieben AWT, Swing, JavaFX & SWT 5
A SWT Tooltip soll nicht verschwinden, solange User mit Maus auf Control ist AWT, Swing, JavaFX & SWT 5
J "Auswahlfenster" mit Maus auf JLabel zeichnen AWT, Swing, JavaFX & SWT 4
W Swing Bild zeichnen wenn Maus an bestimmter Position ist AWT, Swing, JavaFX & SWT 4
J Inaktivität von Maus und Tastatur AWT, Swing, JavaFX & SWT 4
G AWT Images aus Imagearray an die Maus pappen und bewegen AWT, Swing, JavaFX & SWT 4
F Element anzeigen / erstellen. Maus vs Controller AWT, Swing, JavaFX & SWT 7
M 3D-Grafik Bewegung mit der Maus ohne Klicken AWT, Swing, JavaFX & SWT 10
F Swing Objekte mit Maus verschieben AWT, Swing, JavaFX & SWT 8
O Swing JButton werden richtig gewechselt aber die Maus macht die alten wieder Sichtbar?? AWT, Swing, JavaFX & SWT 5
Y AWT Maus Koordinaten abspeichern in eine Textfile AWT, Swing, JavaFX & SWT 3
Weltall 7 AWT Maus-Events werden doppelt ausgeführt AWT, Swing, JavaFX & SWT 12
C permanente aktualisierung der Koordinaten der Maus auf einem Panel AWT, Swing, JavaFX & SWT 8
J maus festlegen AWT, Swing, JavaFX & SWT 6
C paintComponent mit Maus verschieben - wie? AWT, Swing, JavaFX & SWT 2
T Swing JComboBox: Listeneinträge mit der Maus verschieben AWT, Swing, JavaFX & SWT 5
O JSlider - wie unterscheide ich mit Maus verändert und durch setValue verändert. AWT, Swing, JavaFX & SWT 16
W Swing Maus Rastersprung AWT, Swing, JavaFX & SWT 3
S Swing JTable Auswahl mehrerer Zellen mit STRG+Maus AWT, Swing, JavaFX & SWT 3
E Hilfetext anzeigen beim Überfahren mit der Maus AWT, Swing, JavaFX & SWT 3
G Maus über Button AWT, Swing, JavaFX & SWT 3
S Funktion nur ausführen, wenn Maus über Componente ist AWT, Swing, JavaFX & SWT 2
G Listenelemente mit der Maus verschieben AWT, Swing, JavaFX & SWT 4
B kein MouseEvent bei zu schneller Bewegung der Maus AWT, Swing, JavaFX & SWT 7
B JTable - Wechsel der Spalte bei TAB, RETURN oder Maus AWT, Swing, JavaFX & SWT 5
D Mit der Maus in verschiedene Modi wechseln AWT, Swing, JavaFX & SWT 15
Z Buttons erscheinen erst wenn man mit der Maus drüber geht AWT, Swing, JavaFX & SWT 7
G Elemente erst da wenn mit Maus drüber gefahren bin AWT, Swing, JavaFX & SWT 2
M Kreis mit gedrückter Maus bewegen AWT, Swing, JavaFX & SWT 20
F Größenänderung mittels Maus - selbst implementieren? AWT, Swing, JavaFX & SWT 3
R Einstellen der Maus Rad Geschwindigkeit beim Scrollen AWT, Swing, JavaFX & SWT 3
G Kreis zeichnen und mit Maus ziehen AWT, Swing, JavaFX & SWT 3
W Maus Rahmen zeichnen AWT, Swing, JavaFX & SWT 10
A JFileChooser - Mehrere Dateien per Maus markieren (nokeys) AWT, Swing, JavaFX & SWT 7
V JTable Handling Fokus on Keystroke und Maus Doubleclick AWT, Swing, JavaFX & SWT 9
R JTable: Maus-Click ohne Datensätze AWT, Swing, JavaFX & SWT 9
L Größe von Komponenten im Nulllayout mit der Maus verändern. AWT, Swing, JavaFX & SWT 2
J Context Menü Maus AWT, Swing, JavaFX & SWT 3
G JTable selektion der Zeile bei Fokusieren mit der Maus AWT, Swing, JavaFX & SWT 5
T mousemoved abfrage - aber welches event wenn maus weg? AWT, Swing, JavaFX & SWT 2
lin Frame bei Drücken eines Buttons mit Maus verschieben AWT, Swing, JavaFX & SWT 7
G [AWT] Zeichnungen per Maus auswählen AWT, Swing, JavaFX & SWT 8
D Ne Maus Event Frage AWT, Swing, JavaFX & SWT 4
D Polygon mit der Maus zeichnen AWT, Swing, JavaFX & SWT 2
M Zusätzlichen Maus-Klick erzeugen AWT, Swing, JavaFX & SWT 4
T Cursor im JPanel fangen AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben