# gezeichnete Punkte dynamisch verschieben mit mousedragged



## manni (26. Apr 2006)

Hallo,

ich schreibe gerade eine Java Applikation, bei der ich gezeichnete Punkte mittels gedrückter Maustaste verschieben möchte.

Dazu verwende ich die Methode mousedragged, die dann eine weitere Methode "changePoint" aufruft, die zuerst nachsieht, ob ich in der Nähe eines bestehenden Punktes geklickt habe, und erst dann weitere Berechnungen ausführt...usw.
Das funktioniert soweit auch, das Problem ist nur, wenn ich den Punkt zu schnell bewege, dann "verliert" er sozusagen den zu bewegenden Punkt. 
Halte ich die Maustaste weiter gedrückt und fahre zurück zur letzten Position, dann kann ich den Punkt weiterbewegen.

Hat jemand eine Idee, wie ich das Problem beheben kann?

Code-Auszug:

```
public synchronized void mouseDragged(MouseEvent event)
         {
         	m_ClickX = event.getX();
         	m_ClickY = event.getY();
         	System.out.println("drag");
        	m_Canvas.changePoint(m_ClickX,m_ClickY);
         }
```


```
public synchronized boolean changePoint(int PosX, int PosY) {
			m_Point = new PointCP(PosX,PosY); 
			System.out.println("drag: "+PosX+" "+PosY);
			if (m_PointList.size()>3 && m_CHpoints>3) { // remove is only allowed, when a minimum of 3 points left
				for (int i=0;i<m_PointList.size();i++) {
					for (int a=-4;a<=4;a++) {
						for (int b=-4;b<=4;b++){
							if(m_Point.getX()+a==((PointCP)m_PointList.get(i)).getX() &&
									m_Point.getY()+b==((PointCP)m_PointList.get(i)).getY()) {
								System.out.println("drag");
								((PointCP)m_PointList.get(i)).setX(m_Point.getX()); 
								((PointCP)m_PointList.get(i)).setY(m_Point.getY()); 
								SEC_CHull();
								repaint(); // repaints the JCanvas
								break;
							}
						}
					}
				}
			}
```


----------



## André Uhres (26. Apr 2006)

manni hat gesagt.:
			
		

> ...Dazu verwende ich die Methode mousedragged, die dann eine weitere Methode "changePoint" aufruft,
> die zuerst nachsieht, ob ich in der Nähe eines bestehenden Punktes geklickt habe...


Nachsehen, ob du in der Nähe eines bestehenden Punktes geklickt hast ist ja schon notwendig.
Aber das darfst du nicht in mousedragged machen, sondern in mousePressed. 

Dazu musst du zusätzlich zum MouseMotionListener einen MouseListener hinzufügen. 
In mousePressed setzt du eine boolsche Variable die angibt ob ein Punt zu bewegen ist oder nicht 
und berechnest auch die Position des Mauszeigers relativ zu dem Punkt in dessen Nähe er ist (deltaX, deltaY).

In mousedragged fragst du dann die boolsche Variable ab und berechnest die neue Position 
mit Hilfe von deltaX und deltaY. Hoffe das hilft.

```
/*
 * PunktVerschieben2.java
 */
//package paint;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PunktVerschieben2 extends JFrame {
    public PunktVerschieben2() {
        super("Punkt verschieben");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400,400);
        setLocationRelativeTo(null);
        punktPanel = new PunktPanel();
        add(punktPanel);
    }
    public static void main(String args[]){new PunktVerschieben2().setVisible(true);}
    private PunktPanel punktPanel;
    class PunktPanel extends JPanel implements MouseListener, MouseMotionListener{
        public PunktPanel(){
            addMouseListener(this);
            addMouseMotionListener(this);
        }
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawPolygon(new int[]{x1, x2, x3}, new int[]{y1, y2, y3}, 3);
        }
        private void setPumkt(int x, int y){
            switch(p){
                case 1:{x1 = x; y1 = y; break;}
                case 2:{x2 = x; y2 = y; break;}
                case 3:{x3 = x; y3 = y; break;}}
            repaint();
        }
        public void mouseDragged(MouseEvent e) {
            if(move) setPumkt(e.getX()+deltaX, e.getY()+deltaY);
        }
        public void mouseMoved(MouseEvent e) {}
        public void mouseClicked(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {
            int xP = e.getX();
            int yP = e.getY();
            move = false;
            if(xP > x1-10 && xP < x1+10 && yP > y1-10 && yP < y1+10){
                deltaX = x1-xP; deltaY = y1-yP; move = true; p=1;
            }else if(xP > x2-10 && xP < x2+10 && yP > y2-10 && yP < y2+10){
                deltaX = x2-xP; deltaY = y2-yP; move = true; p=2;
            }else if(xP > x3-10 && xP < x3+10 && yP > y3-10 && yP < y3+10){
                deltaX = x3-xP; deltaY = y3-yP; move = true; p=3;
            }
        }
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
        private int x1=200, y1=30, x2=200, y2=200, x3=300, y3=300, deltaX, deltaY, p;
        private boolean move;
    }
}
```


----------



## manni (26. Apr 2006)

Ich habe schon eine Methode mousepressed, die verwende ich um bei Klick einen Punkt zu setzen, und bei rechts-Klick einen Punkt zu löschen!
Aber jetzt möchte ich diese Punkte dynamisch am Bildschirm verschieben.
Da jeder Punkt Ecke eines Polygons ist, werden die Kanten gleich neu berechnet und das wird sofort dargestellt, d.h. die Linien bewegen sich mit dem Punkt mit.

Ich möchte also die Punkte bewegen und ziehe dabei die Polygonlinien wie ein Gummiband mit!

Deshalb bin ich mir jetzt nicht sicher, ob mir dein Tipp schon hilft?


----------



## Leroy42 (26. Apr 2006)

Früher bei den langsamen GUI's war das nicht so einfach. Man mußte erst die alte
Linie mit einer XOR-Verknüpfung überschreiben und dann die neue Linie zeichnen.

Heutzutage kannst du dir das schenken und via repaint() die GUI einfach anweisen,
alles neu zu zeichnen.

Du brauchst also nur in der mouseDragged Methode die Koordinate des Punktes
den du in der mousePressed Methode selektiert hattest speichern und alles neu zeichnen.


----------



## André Uhres (26. Apr 2006)

manni hat gesagt.:
			
		

> ...Ich möchte also die Punkte bewegen und ziehe dabei die Polygonlinien wie ein Gummiband mit!
> Deshalb bin ich mir jetzt nicht sicher, ob mir dein Tipp schon hilft?


Ob du einen fillOval oder einen drawPolygon machst dürfte ziemlich egal sein.


----------

