# Java, Swing: MouseMotionListener



## matthiasS (24. Aug 2006)

Hallo,

habe eine kleine Frage, evtl. könnt ihr mir ja helfen ...
Folgendes habe ich vor: Ich moechte einzelne Fußballspieler (in meinem Fall, Quadrate in paint() gezeichnet [aus JComponent abgeleitet]) auf einem Spielfeld (ebenfalls ein JComponent) platzieren und diese mit der Mouse spaeter verschieben können. Ich sollte dazu sagen - nur zu Lernzwecken. Einen besonderen Sinn hat das alles nicht.  Folgendes habe ich dazu gemacht. Habe mir auf meine ContentPane ein LayererdPane gelegt, auf der untersten Ebene das Spielfeld und darueber die Spieler platziert. Wie gesagt, die Spieler will ich verschieben koennen. Habe dazu den MouseMotionListener implementiert und an die einzelnen Spieler hinzugefuegt. Meine draggedMouse()-Methode macht nichts anderes als { e.getComponent().setLocation(e.getX(),e.getY()); } e ist das MouseEvent. Dachte, dass dies ausreichen muesste, um die Komponente an meinen Mousezeiger zu binden, allerdings verschiebt sich das Objekt nur sehr unschoen. Es bleibt nicht an der Mouse "kleben" und die Position, auf der es platziert wird, ist mir auch nicht ganz klar ...


Vieleicht habt ihr ja einen Rat ...

Vielen Dank im Voraus
Matthias


----------



## Wildcard (24. Aug 2006)

In Swing überschreibt man paintComponent, und nicht paint.
Du musst dir erstmal einen Offset ausrechnen. setLocation bezieht sich auf die linke-obere Ecke deiner Component, während der Mauszeiger in der regel irgendwo in der Mitte der Komponente ist.


----------



## matthiasS (24. Aug 2006)

Danke, fuer die rasche Antwort. Habe meine paint-Methode umbenannt. Wenn ich an der Komponente ziehe, hat man immer das gefühl, als wolle sie sich am oberen linken Rand des Fensters festhalten. Die Komponente laesst sich auch nicht "durchgaengig" ziehen - sie verschwindet immer und taucht dann wieder auf. Der MouseZeiger wirkt "schneller", als die Komponente. Vielen Dank im Voraus.

Gruß
Matthias


----------



## Wildcard (24. Aug 2006)

Ich hab dir doch gesagt das du einen Offset brauchst. Hast du das gemacht? Wenn ja, zeig mal den Code


----------



## matthiasS (24. Aug 2006)

Die Komponente ist 50x30 pixel groß. 
Hier meine mouseDragged-Methode:

```
public void mouseDragged(MouseEvent e) {
		
		e.getComponent().setLocation(e.getX()-25,e.getY()-15);
	
		System.out.println("ziehe spieler ... ");
	}
```

in der Klasse, in der ist die Objekte bilde steht folgendes:

```
Spieler blubb = new Spieler();
        blubb.addMouseMotionListener(this);
        blubb.setBounds(60, 170, 50, 30);
...
        layeredPane.add(blubb, new Integer(2), 0);
```

Dankeschoen!


----------



## Wildcard (24. Aug 2006)

Nein, so meine ich das nicht.
Bei mousePressed musst du dir den Punkt speichern.
Bei mouseDragged nimmst du dann den neuen Punkt, und errechnest du den Offset, also um wieviel sich die Maus bewegt hat.
Dann bewegst du deine JComponent um diesen Offset


----------



## matthiasS (24. Aug 2006)

Danke.

Habe nun folgendes Problem. An meine JComponent fuege ich zum einen den MouseMotionListener und zum anderen den MouseListener hinzu. Loese ich auf meiner Komponente nun ein mousePressed Event aus, dann bekomme ich die x und y Koordinaten nur in Bezug auf meine Komponente. Sprich, klicke ich links oben bekomme, ich fuer x und y den Wert 0 ... Wenn ich die Komponente nun "dragge" und auf meiner Flaeche ziehe, bekomme ich die Koordinaten immer in Bezug auf mein Fenster ( die werden dann also sehr groß verglichen mit dem pressed-Event), bzw. die Flaeche unterhalb meiner Spieler. Wie soll ich da denn dann den Offset errechnen?

Danke im Voraus,
Matthias


----------



## Wildcard (24. Aug 2006)

```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JFrame;


public class Drag extends JFrame
{
	
	public Drag()
	{
      setLayout(null);
		add(new Dragable());
	}
	
	public static void main(String[] args)
	{
		Drag drag = new Drag();
		drag.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		drag.setSize(640,480);
		drag.setVisible(true);
	}
	
	class Dragable extends JComponent implements MouseMotionListener
	{
		private Point offset;
		
		public Dragable()
		{
			setSize(50, 50);
			addMouseListener(new MouseAdapter() {
			
				@Override
				public void mousePressed(MouseEvent e)
				{
					offset=e.getPoint();
				}
			});
			addMouseMotionListener(this);
		}

		@Override
		protected void paintComponent(Graphics g)
		{
			g.setColor(Color.BLUE);
			g.fillRect(0, 0, 50, 50);
		}

		public void mouseDragged(MouseEvent e)
		{
			setLocation(getX()+e.getPoint().x-offset.x,getY()+e.getPoint().y-offset.y);
		}

		public void mouseMoved(MouseEvent e)
		{
			// TODO Auto-generated method stub
			
		}		
	}

}
```


----------



## matthiasS (25. Aug 2006)

Danke dir. Das hat funktioniert!


----------



## matthiasS (25. Aug 2006)

Eine Frage haette ich da noch.
Und zwar zu folgender Zeiler:

```
setLocation(getX()+e.getPoint().x-offset.x,getY()+e.getPoint().y-offset.y);
```

e.getPoint().x ist ja die X-Koordinate des MouseZeigers innerhalb der JComponent (also im Intervall in meinem Fall von 0 bis 30 bzw. 50)  zum Zeitpunkt des Draggens, richtig? Mein alter Wert - also der Offset zum Zeitpunkt des mousePressed-Events ist nicht großartig vom ersten Wert verschieden. Hoechstens um 1 - 2 Einheiten. Ich verstehe gerade nicht, wieso ich diesen Offset errechnen muss ... wäre super, wenn du mir das nochmal versuchen könntest zu erklären. Stehe gerade etwas auf dem Schlauch, Sorry!


----------



## Leroy42 (25. Aug 2006)

_e.getPoint().x - offset.x_ ist tatsächlich nur minimal, allerdings
nur _beim ersten Mal_!

Nimm einfach mal die Subtraktionen der offset-Werte heraus und starte
das Programm dann nochmal. Dann wirst du den Unterschied bemerken.


----------



## matthiasS (25. Aug 2006)

die Figuren lassen sich dann nicht mehr bewegen. die differenzen zwischen offset und den werten beim draggen steigen. stehe dennoch auf dem schlauch. :/ kann das nochmal so wiedergeben, dass ich es verstehe ... :/

Danke im Voraus


----------



## Leroy42 (25. Aug 2006)

matthiasS hat gesagt.:
			
		

> die Figuren lassen sich dann nicht mehr bewegen


Das ist falsch! Ich habe es selbst ausprobiert!  :noe: 

Wenn du


```
setLocation(getX()+e.getPoint().x, getY()+e.getPoint().y);
```

schreibst, bewegt sich das blaue Rechteckt schon, allerdings _springt_ es
bei der ersten Bewegung so, daß sich seine linke, obere Ecke genau unter dem
Mauszeiger befindet, unabhängig davon _wo_ du es mit der Maus angeklickt hast.


----------



## matthiasS (25. Aug 2006)

Ah ok. Habe bis auf getX() und getY() alles entfernt. Was ich nicht ganz verstehe ist, warum ich nicht einfach alles weglassen kann. Schließlich benoetige ich ja immer nur die neue Position des Mousezeigers mit der JComponent zu synchronisieren.


----------



## Wildcard (25. Aug 2006)

Dann ziehst du die Komponente aber immer an der linken oberen Ecke, was ich als Benutzer als sehr störend empfinden würde.
Warum machst du's nicht einfach so wie ich dir gezeigt habe?


----------



## Leroy42 (25. Aug 2006)

matthiasS hat gesagt.:
			
		

> Habe bis auf getX() und getY() alles entfernt.



Was ich dir nicht glaube denn ein

```
setLocation(getX(),  getY());
```
dürfte schließlich _überhaupt nichts_ bewirken!


----------



## Leroy42 (25. Aug 2006)

Wildcard hat gesagt.:
			
		

> Warum machst du's nicht einfach so wie ich dir gezeigt habe?



Vielleicht weil er zu den Menschen gehört, die den _Sachen auf den Grund_ gehen wollen?  :shock: 

Was ihn mir im übrigen sympathischer macht als diejenigen, die einfach nur
eine Antwort in ihren Source kopieren und dann, ohne ihn analysiert zu haben,
damit leben!  :applaus:


----------



## Wildcard (25. Aug 2006)

Leroy42 hat gesagt.:
			
		

> Vielleicht weil er zu den Menschen gehört, die den _Sachen auf den Grund_ gehen wollen?  :shock:
> 
> Was ihn mir im übrigen sympathischer macht als diejenigen, die einfach nur
> eine Antwort in ihren Source kopieren und dann, ohne ihn analysiert zu haben,
> damit leben!  :applaus:


Da gebe ich dir schon recht, nur gibt es glaube ich nichts weiter zu erklären, da wir das bereits bis zur Erschöpfung getan haben  :bae:


----------



## MatthiasS (25. Aug 2006)

Sagte ich ja ... es bewirkt gar nichts.
Aber es ist uebrigens, wie du sagst - ich wuerde es gerne verstehen. Momentan tue ich dies leider nicht ganz. :/
Warum das "Springen" wegfaellt etc.


----------



## Wildcard (25. Aug 2006)

Setz dir Breakpoints in den entsprechenden Methoden, nimm ein kariertes Blatt mit Koordinatensystem und trag die Werte ein. Vieleicht verstehst du es dann.


----------

