# Grafikobjekte mit Mouse auswählen und verschieben



## Maver2000 (25. Mai 2004)

Hi, 

ich bastle an einem Grafikeditor. Und es klappt prima verschiedene Formen, z.B. Polygone und Kreise zu zeichen. Ich möchte diese aber nun im nachhinein per Mouse auswählen und verschieben. Kann mir einer sagen, wie ich das mache. Ich schaffe es nämlich irgendwie nicht den einzelnen Objekten MouseListener zuzuweisen, oder ist das der falsche Ansatz. 

Recht herzlichen Dank.


----------



## L-ectron-X (25. Mai 2004)

Ich habe mal vor einiger Zeit etwas ähnliches in einem funktionstüchtigen Applet programmiert. Es ist aber nie fertig gestellt worden und hat daher seine Macken, macht aber in etwa das, was Du suchst. Im Prinzip dürften für Dich die MouseListener-Methoden interessant sein.

```
//Benötigte Pakete importieren.
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Rechtecke extends Applet {

  private int b, h; //Breite und Höhe des Applets
  private int x, y; //Aktuelle Maus-Koordinaten
  private int x1, y1; //Maus-Koordinaten bei MouseEvents
  private Rectangle r; //Variable vom Typ Rectangle (Rechteck)
  private Vector rechtecke; //Behälter für Rechtecke
  private boolean verschieben = false;

  //die init()-Methode aus Applet
  public void init() {
    rechtecke = new Vector(); //Behälter für die Rechtecke erstellen
    b = getWidth(); //Breite aus dem Applet-Tag
    h = getHeight(); //Höhe aus dem Applet-Tag

    /*Einen MouseListener am Applet anmelden. Hier in einer Variante
    * mit einem MouseAdapter, so brauchen nicht alle Methoden
    * des MouseListeners überschrieben werden.
    */
    addMouseListener(new MouseAdapter() {
      //Wenn die Maustaste gedrückt gehalten wird.
      public void mousePressed(MouseEvent e) {
        //Erfassen der momentanen Maus-Position.
        x = e.getX();
        y = e.getY();
          
        //Wenn bereits Rechtecke im Behälter sind.
        if(!rechtecke.isEmpty()) {
          //Jedes einzelne der Rechtecke holen.
          for(int i = 0; i < rechtecke.size(); i++) {
            r = (Rectangle)rechtecke.elementAt(i);
            //Feststellen ob und auf welche(s) Rechteck(e) geklickt wurde.
            if(r.getX() < x && r.getY() < y && r.getWidth() > x && r.getHeight() > y) {
              /*Das erste gefundene Rechteck ans Ende des Vectors verschieben,
              * damit es beim Zeichnen immer oben liegt.
              * Dann Rechteck als zu verschieben markieren und Methode verlassen.
              */
              rechtecke.add(rechtecke.remove(i));
              verschieben = true;
              return;
            }
          }
        }
      }

      //Wenn die Maustaste wieder losgelassen wird.
      public void mouseReleased(MouseEvent e) {
        //Ungültiger Mausklick
        if(x1 == y1)
          return;
          
        //Wenn auf kein Rechteck geklickt wurde.
        if(!verschieben) {
        //Neues Rechteck erzeugen
          r = new Rectangle(x, y, x1, y1);
          //Das Rechteck dem Behälter hinzfügen.
          rechtecke.add(r);
          repaint();
        }
        //Wenn Maustaste losgelassen wird ist verschieben beendet.
        verschieben = false;
      }
    });

    /*Einen MouseMotionListener am Applet anmelden. Hier in einer Variante
    * mit einem MouseMotionAdapter. MouseMotionListener implementiert zwar
    * nur die zwei folgenden Methoden, so ist es aber auch übersichtlicher.
    */
    addMouseMotionListener(new MouseMotionAdapter() {
      //Wenn die Maus mit gedrückter Maustaste bewegt wird.
      public void mouseDragged(MouseEvent e) {
        setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
        showStatus("Rechteck zeichnen");
        //Koordinaten-Information bei Rechteck zeichnen und Verschieben.
        x1 = e.getX();
        y1 = e.getY();
        if(verschieben)
          verschieben(r);
        //Komplettes Bild neu zeichen incl. Hintergrund
        repaint();
      }
      
      //Wenn die Maus bewegt wird.
      public void mouseMoved(MouseEvent e) {
        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        //Status des Applets in Browser-Statuszeile anzeigen.
        showStatus("Bereit für Benutzeraktion");
        x = e.getX();
        y = e.getY();
        x1 = 0;
        y1 = 0;
        repaint();
      }
    });
  }
  
  //Verschiebt das angeklickte Rechteck.
  private void verschieben(Rectangle r) {
    setCursor(new Cursor(Cursor.MOVE_CURSOR));
    //Status des Applets in Browser-Statuszeile anzeigen.
    showStatus("Rechteck verschieben");
    int breite = (int)(r.getWidth() - r.getX());
    int hoehe = (int)(r.getHeight() - r.getY());
    //Diemension des Rechtecks herstellen
    int x2 = x1 + breite;
    int y2 = y1 + hoehe;
    r.setBounds(x1, y1, x2, y2);
  }

  public void paint(Graphics g) {
    //Den Bereich für die Koordinaten-Ausgabe löschen
    g.clearRect(0, 0, b, h);
    
    //Koordinaten zeichnen
    g.setColor(Color.BLACK);
    g.drawString("x = "+x, 5, 15);
    g.drawString("y = "+y, 55, 15);
    g.drawString("x1 = "+x1, 110, 15);
    g.drawString("y1 = "+y1, 165, 15);
    
    /*Jedes Rechteck aus dem Behälter holen,
    * dessen Werte ermitteln und zeichnen
    */
    for(int i = 0; i < rechtecke.size(); i++) {
      int x = (int)((Rectangle)rechtecke.elementAt(i)).getX();
      int y = (int)((Rectangle)rechtecke.elementAt(i)).getY();
      int breite = (int)((Rectangle)rechtecke.elementAt(i)).getWidth()-x;
      int hoehe = (int)((Rectangle)rechtecke.elementAt(i)).getHeight()-y;
      //Schatten zeichnen.
      g.setColor(Color.GRAY);
      g.drawRect(x+1, y+1, breite, hoehe);
      //Rahmen für das Rechteck zeichnen.
      g.setColor(Color.BLACK);
      g.drawRect(x, y, breite, hoehe);
      //Rechteck füllen.
      g.setColor(Color.WHITE);
      g.fillRect(x+1, y+1, breite-1, hoehe-1);
    }
  }
  
  public void update(Graphics g) {
    g.setColor(getBackground());
    g.fillRect(0, 0, b, h);
    g.setColor(getForeground());
    paint(g);
  }
}
```


----------



## Maver2000 (25. Mai 2004)

Recht herzlichen Dank, dass Applet ist schon zum großen Teil das, wo ich hin will. 


```
if(r.getX() < x && r.getY() < y && r.getWidth() > x && r.getHeight() > y) {
```

Diese Auswertung ist für Rechtecke ja auch noch gut zu realisieren, aber wie handhabe ich das bei nichtgeschlossenen Polygonzügen.

Mir hat mal jemand was davon erzählt, jedes einzelne Grafikobjekt als Container zu initialisieren. Aber das kann ich mir nicht vorstellen, wie das gehen soll, da ich meine Polygone in einer ähnlichen Vektorstruktur habe, wie das bei dir realisiert wurde. Und kann ich den einzelnen Objekten dann MouseListener bzw. MouseMotionListener zuweisen?

Aber zunächst Danke für Deine Hilfe, es hat mich schon ein ganzes Stück weiter gebracht.


----------

