# GUI Kreis zeichnen



## scsv2504 (11. Feb 2019)

Hallo, hänge an folgender Aufgabe:
"Es soll ein JFrame geschrieben werden, der über MouseAdapter bei MousePressed den aktuellen Punkt der Maus als Mittelpunkt speichert und bei MouseDragged einen Kreis zeichnet mit dem Abstand zwischen Mittelpunkt und Maus als Radius"


```
public class kreiszeichnen extends JPanel{
    Point mittelPunkt = new Point();
    int radius=0;
   
    public class MeinMouseListener extends MouseAdapter{
        public void mousePressed(MouseEvent e) {
            mittelPunkt=e.getPoint();
           
        }
        public void mouseDragged(MouseEvent e) {
            radius=mittelPunkt.x-e.getX();
repaint();
           
        }       
    }
   
    public kreiszeichnen() {
        MeinMouseListener listener= new MeinMouseListener();
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }
    public void paint(Graphics g) {
        g.fillOval(mittelPunkt.x, mittelPunkt.y, radius, radius);
    }
public static void main(String[] args) {
    JFrame mf=new JFrame();
    mf.setSize(250, 150);
    mf.setVisible(true);
    mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JComponent n=new kreiszeichnen();
    mf.setContentPane(n);
    n.setOpaque(false);
}
}
```

Kann mir jemand weiterhelfen? Wenn ich das Programm zum Laufen bringe, passiert nichts...


----------



## mihe7 (11. Feb 2019)

scsv2504 hat gesagt.:


> Wenn ich das Programm zum Laufen bringe, passiert nichts...


Bei mir wird ein Fenster angezeigt.


----------



## Robat (11. Feb 2019)

Ein paar Hinweise:
- berechne den absoluten Wert zwischen Mittelpunkt und aktueller Mauskoordinate (negative Radien gibt es noch nicht  )
- setVisible(true) erst zum Schluss aufrufen
- benutz paintComponent(Graphics) anstatt paint(Graphics)


----------



## Thallius (11. Feb 2019)

Schon in alle vier Richtungen versucht die Maus zu bewegen?


----------



## scsv2504 (11. Feb 2019)

mihe7 hat gesagt.:


> Bei mir wird ein Fenster angezeigt.


Bei mir auch, ich meine der Kreis wird nicht gezeichnet.



Robat hat gesagt.:


> Ein paar Hinweise:
> - berechne den absoluten Wert zwischen Mittelpunkt und aktueller Mauskoordinate (negative Radien gibt es noch nicht  )
> - setVisible(true) erst zum Schluss aufrufen
> - benutz paintComponent(Graphics) anstatt paint(Graphics)



paint(Graphics) ist von der Aufgabe her vorgegeben...
Vielen Dank für den Tipp mit dem Radius, jetzt hat es geklappt!

/edit: eine Frage hätte ich dennoch, jetzt ist das ganze aber nicht der Mittelpunkt wenn ich den Kreis zeichne. Wie würde man das hinkriegen?


----------



## Robat (11. Feb 2019)

```
g.fillOval(mittelPunkt.x-(radius/2), mittelPunkt.y-(radius/2), radius, radius);
```


----------



## mihe7 (11. Feb 2019)

scsv2504 hat gesagt.:


> Bei mir auch, ich meine der Kreis wird nicht gezeichnet.


Ich weiß 



scsv2504 hat gesagt.:


> Wie würde man das hinkriegen?


Beim Zeichnen gibst Du das Oval durch ein Rechteck an (links, oben, Breite, Höhe). Du musst also nur die Koordinaten entsprechend anpassen. Noch ein kleiner Hinweis: Breite ist nicht der Radius.

EDIT: @Robat war schneller.


----------



## scsv2504 (11. Feb 2019)

Robat hat gesagt.:


> ```
> g.fillOval(mittelPunkt.x-(radius/2), mittelPunkt.y-(radius/2), radius, radius);
> ```



bin etwas verwirrt, wie kommst du zu dem Code? Könntest du versuchen die ersten zwei Koordinaten zu erläutern bitte?


----------



## Robat (11. Feb 2019)

scsv2504 hat gesagt.:


> bin etwas verwirrt, wie kommst du zu dem Code? Könntest du versuchen die ersten zwei Koordinaten zu erläutern bitte?


Siehe Antwort von @mihe7


----------



## scsv2504 (11. Feb 2019)

Robat hat gesagt.:


> Siehe Antwort von @mihe7


genau, aber woher das radius/2 kommt ist mir immer noch nicht klar...


----------



## mihe7 (11. Feb 2019)

Wenn radius tatsächlich den Radius meint, müsste es richtig heißen

```
g.fillOval(mittelPunkt.x-radius, mittelPunkt.y-radius, radius*2, radius*2);
```


----------



## scsv2504 (11. Feb 2019)

mihe7 hat gesagt.:


> Wenn radius tatsächlich den Radius meint, müsste es richtig heißen
> 
> ```
> g.fillOval(mittelPunkt.x-radius, mittelPunkt.y-radius, radius*2, radius*2);
> ```


zum Verständnis, fillOval's breite mal höhe ist als Durchmesser jeweils anzusehen, richtig? Dann macht dein Code auch völlig Sinn. Vielen Dank an alle


----------



## mihe7 (11. Feb 2019)

scsv2504 hat gesagt.:


> zum Verständnis, fillOval's breite mal höhe ist als Durchmesser jeweils anzusehen, richtig?


Ja, wie bereits geschrieben: Du gibst das Rechteck an, in das das Oval gezeichnet werden soll.

Mal im Zusammenhang:

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test {

    private static class KreisPanel extends JPanel {
        private Point mittelpunkt = new Point();
        private int radius=0;

        public void setMittelpunkt(Point p) {
            mittelpunkt = p;
        }

        public void setRandpunkt(Point p) {            
            int dx = mittelpunkt.x - p.x;
            int dy = mittelpunkt.y - p.y;
            setRadius((int)(Math.sqrt(dx*dx + dy*dy)));
        }

        public void setRadius(int radius) {
            this.radius = radius;
            repaint();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.fillOval(mittelpunkt.x - radius, mittelpunkt.y - radius, 
                       radius*2, radius*2);
        }
    }
 
    public class Kreiszeichner extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            KreisPanel panel = (KreisPanel) e.getComponent();
            panel.setMittelpunkt(e.getPoint());
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            KreisPanel panel = (KreisPanel) e.getComponent();
            panel.setRandpunkt(e.getPoint());
        }      
    }
   
    public void createAndShowGUI() {
        KreisPanel panel = new KreisPanel();
        Kreiszeichner listener= new Kreiszeichner();
        panel.addMouseListener(listener);
        panel.addMouseMotionListener(listener);

        JFrame mf=new JFrame();
        mf.add(panel);
        mf.setSize(250, 150);
        mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mf.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().createAndShowGUI());
    }
}
```


----------



## scratchy1 (13. Sep 2019)

Hallo Leute,
ich habe ein ähnliches Problem,
ich will ein (EggTimer)-Canvas der Größe 320x320 bauen und darin
einen Kreis mit 300 Pixel Durchmesser setzen:
Die Methode paint (Graphics g) ist auch vorgegeben


```
public void paint(Graphics g) {

g.drawOval(10, 10, 299, 299);
```
Ich habe  das wie folgt angesetzt:
width und height sind 300 Pixel da in der Doku steht 
"The oval covers an area that is width + 1 pixels wide and height + 1 pixels tall ", habe ich 299 genommen. 
Jetzt muss ich noch rausfinden, was x und y sind:

x=320/2-radius
y=320/2-radius

Der Radius ist 150, also sind
x=160-150=10
y=160-150=10 ? 

Ist mein Ansatz richtig?


----------

