PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schon wieder Java: diesmal MouseMotionListener


RMC
2005-10-31, 12:14:50
Folgendes:

Ich hab ein einfaches Objekt, dem ich einen MouseMotionListener zugewiesen hab. in der mouseDragged() Methode verschieb ich das Objekt. Wenn ich dann die Maus loslasse, ist der Listener aber noch an der Startposition, während das Objekt schon wo anders steht, d.h. der Listener folgt dem Objekt nicht.


Wenn ich also auf die Startposition (zb 0,0) klicke, das Objekt verschiebe und dann loslasse, befindet sich das Objekt zb auf 40,100 und der Listener immer noch auf 0,0.

Ich kann das Objekt also nur verschieben, wenn ich wieder auf 0,0 klicke.


Innerhalb der mouseDragged() Methode zeichne ich das Objekt neu, indem ich paint() aufrufe.



Wie kann ich es anstellen, dass der Listener dem Objekt "folgt", wenn ich es verschiebe?

Danke!

Monger
2005-10-31, 17:55:42
Erstmal nur aus Interesse: verwendest du Swing?


Dann: Was meinst du damit, "der Listener folgt deinem Button nicht"? Der Listener hat doch keine graphische Repräsentation ?!?
Der Button selbst setzt ja das Ereignis ab. Die Listener hören nur zu, um den Befehl dann zu verarbeiten.


Gefühlsmäßig würde ich sagen, dass sich dein Fenster nicht ausreichend updated. D.h. der Button wird zwar neu gezeichnet, aber die Positionsangabe wird an das umfassende Fenster nicht weitergeleitet. Wenn du JComponents aus Swing verwendest, kannst du mal #validate() ausprobieren. Ansonsten sollten wir alle mal laut nach HellHorse rufen! :D

RMC
2005-10-31, 18:30:19
Ja ich verwende Swing.

Ich will einen eigenen Slider bauen. Das Slide-Element selbst (welches sich bewegt) ist ein eigenes Objekt, welches von JComponent ableitet und ein Bild beinhaltet. Diesem Objekt weise ich einen MouseMotionListener zu, damit man es draggen kann...is klar oder?

Gut, danach beweg ich dieses Objekt hin und her, je nach dem wie sich die x-Koordinate ändert. Nachdem dann mit paint() alles neu gezeichnet wird bleibt der Listener einfach nicht bei dem Objekt! Das Objekt bewegt sich zb +50 auf der x-Achse, während der Listener noch am Ursprungsort bleibt. Das kann ich deshalb erkennen, weil der Cursor zum Hand-Cursor wird, sobald ich mit der Maus über das Slide-Element fahre.

Was passiert also? Beim Ursprungsort bekomme ich den Hand-Cursor (Indiz dafür dass der Listener dort noch ist) und sobald ich dort wieder zu draggen beginne, kann ich das Objekt wieder verschieben, wobei es dann wieder logischerweise am Ursprungsort gezeichnet wird.

Monger
2005-10-31, 19:58:38
Probier mal bitte validate() statt paint() aus!

Validate führt nicht nur ein neuzeichnen durch, sondern baut auch inhaltlich das jeweilige Element (inklusive aller Kind-Elemente) neu auf.

RMC
2005-10-31, 20:16:42
validate() macht leider gar nix, das Slide-Element bewegt sich keinen Millimeter. Auch wenn ich die Funktion zusätzlich aufrufe bleibt es leider beim Alten.

HellHorse
2005-10-31, 21:59:44
Also wenn du den Ursprungsort wissen willst, den kriegst du per #mousePressed von MouseListener. Die aktuelle Position kriegst du mittels #getPoint des Events.

Ich sehe aber ehrlich gesagt das Problem nicht ganz. Geht doch problemlos ohne Ursprungspunkt.
public class RMCPanel extends JComponent implements MouseMotionListener {

private Point point;

public RMCPanel() {
this.addMouseMotionListener(this);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.point != null) {
g.setColor(BLACK);
g.fillOval((int) this.point.getX() - 4, (int) this.point.getY() - 4, 8, 8);
}
}

public void mouseDragged(MouseEvent e) {
this.point = e.getPoint();
this.repaint();
}

public void mouseMoved(MouseEvent e) {
if (this.point != null) {
Cursor hand = Cursor.getPredefinedCursor(HAND_CURSOR);
if (e.getPoint().distance(this.point) < 4) {
if (this.getCursor() != hand) {
this.setCursor(hand);
}
} else {
if (this.getCursor() == hand) {
this.setCursor(Cursor.getDefaultCursor());
}
}
}
}

public static void setUp() {
JFrame frame = new JFrame("RMC Demo");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

frame.add(new RMCPanel());
frame.setSize(300, 300);
frame.setVisible(true);
}

public static void main(String[] args) {
invokeLater(new Runnable() {
public void run() {
setUp();
}
});
}
}

RMC
2005-10-31, 22:16:11
Ich bin grad auf was draufgekommen:

Mein Slider besitzt Bounds, da ich mit dem Null-Layout arbeite. Daraufhin hab ich ganz einfach beim Loslassen des Mausbuttons die Bounds aktualisiert. Blöderweise ruft er anscheind nach setBounds() automatisch die Methode repaint() auf, was mir dann mein ganzes Bild zerstört.

RMC
2005-11-01, 22:48:59
@Hellhorse:

ok danke. Ich habs ausprobiert und es geht, allerdings taucht jetzt wieder ein anderes Problem auf.

Wenn ich dann im Programmablauf einem Component (zb JPanel) 2 andere Components hinzufüge und die übereinander liegen, dann liegt nach dem Aufruf der Paint Methode Component 1 UNTER Component 2 obwohl es nach dem Programmablauf genau umgekehrt sein sollte, da ich zuerst 1 und dann 2 hinzufüge - mit add() natürlich.

Dazu ist zu sagen, dass sich jedes Component selber zeichnet und sie dieselben x und y Koordinaten haben (also rein optisch übereinander liegen). Irgendwas hats da mit der Reihenfolge.

EDIT:
D.h. ich hab ein JPanel und adde ein Quadrat und dann adde ich genau darüber nochmal einen Kreis...beim painten liegt dann der Kreis UNTER dem Quadrat. So ist das gemeint.


Hast du eine Ahnung?