# ArrayList Rectangles2D



## plammy (22. Jun 2012)

Hallo 
ich habe folgendes Problem.. Ich will mit 2 verschiedene Buttons 2 Verschiedene Rechtecke(ein in grau und ein orange) zeichnen. Jedes mal bei Drücken des Button sollen immer wieder weitere erstellt werden (zb 5 mal drücken des Button werden 5 orange rechtecke erstellt).. die kann man dann bewegen und skalieren... es klappt alles soweit, aber.. wenn ich ein grauen erstellt hab zb und dann ein orangenen erstellt will wird er auf dieselbe position erstellt wo sich grade ein grauen befinden(ich hab den zb vorher iwohin bewegt)... ich denke es werde alle rechtecke die ich will erstellt aber immer an der aktuelle position wo der vorige recjteck sich grade befindet... soll natürlich nicht so sein...


```
public class EditPanel extends JPanel
{

    static  boolean drawRect = false;
    static  boolean drawOrangeRect = false;
   
    List<Rectangle2D.Float> rectangles = new ArrayList<>();
    Rectangle2D.Float rec = new Rectangle2D.Float(0,0,100,100);
    
    //Colors
    Color grayRect = new Color(230,227,224);
    Color orangeRect = new Color(211,111,53);

    MovingAdapter ma = new MovingAdapter();

    /*
     * Konstruktor
     */
    public  EditPanel()
    {        
        addMouseMotionListener(ma);
        addMouseListener(ma);
        addMouseWheelListener(new ScaleHandler());
    } 


    /*
     * Zeichenmethode verschiedener Rechtecken
     */
    protected void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
     
		//wenn drawRect auf true gesetzt ist (was man mit dem Button IndividualForms tut) wird einen grauen Rect gezeichnet
        if(drawRect)
        {
            borderrect(g);
        }
        //wenn drawOrangeRect auf true gesetzt ist (was man mit dem Button OrangeForms tut) wird einen orangenen Rect gezeichnet
        if(drawOrangeRect)
        {
            filledrect(g);
        }
     
    }

     
    /* 
     * Erstellt ein Rechteckt mit grauem Rahmen
     */
    public void borderrect (Graphics g)
    {        
        Graphics2D g2d = (Graphics2D) g;

        g2d.setPaint(Color.LIGHT_GRAY);
        g2d.setStroke(new BasicStroke(2.0f));
        
        rectangles.add(rec);
      
        for (Rectangle2D r : rectangles) 
        {
            g2d.draw(r);
        }     
            
    }
    
    /* 
     * Erstellt ein orangenes Rechteckt
     */
    public void filledrect (Graphics g) 
    {       
        Graphics2D g2d = (Graphics2D) g;
     
        g2d.setPaint(orangeRect);
  
        rectangles.add(rec);
         
        for (Rectangle2D r : rectangles) 
        {
            g2d.fill(r);
        }      
    }
    
    
    /*
     * Hier werden die Aktionen definiert, wie sich der erstellte Rechteck beim
     * Mausdraggen und Mausclicken verhält
     */
    class MovingAdapter extends MouseAdapter 
    {
        private int x;
        private int y;

        public void mousePressed(MouseEvent e) 
        {
            x = e.getX();
            y = e.getY();
        }

        public void mouseDragged(MouseEvent e) 
        {
            int dx = e.getX()-x;
            int dy = e.getY()-y;

            if (rec.getBounds2D().contains(x, y)) 
            {
                rec.x = rec.x + dx;
                rec.y = rec.y + dy;
                repaint();
            }
            x = x + dx;
            y = y + dy;
        }
    }

  
    /*
     * Hier werden die Aktionen definiert, wie sich der erstellte Rechteck beim
     * Scrollen mit der mittlere Taste verhält
     */
    class ScaleHandler implements MouseWheelListener 
    {
        public void mouseWheelMoved(MouseWheelEvent e) 
        {
            int x = e.getX();
            int y = e.getY();

            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) 
            {
                if (rec.getBounds2D().contains(x, y)) 
                {
                    float amount = e.getWheelRotation() * 5f;
                    rec.width = rec.width + amount;
                    rec.height = rec.height + amount;
                    repaint();
                }
            }
        }
    }

    
}
```


----------



## Plopo (22. Jun 2012)

Du benutzt immer wieder das gleiche "Rectangle Object".
Somit ist es logisch, dass die Rechtecke auf der gleichen Stelle erscheinen.

Du musst für JEDES Rechteck ein neues "Rectangle Object" erzeugen.


```
public class EditPanel extends JPanel
{
    static  boolean drawRect = false;
    static  boolean drawOrangeRect = false;
   
    List<Rectangle2D.Float> rectangles = new ArrayList<>();
    //HIER GAB ES EINE ÄNDERUNG - lösche deine Instanzvariable "rec"
    
    //Colors
    Color grayRect = new Color(230,227,224);
    Color orangeRect = new Color(211,111,53);
 
    MovingAdapter ma = new MovingAdapter();
 
    /*
     * Konstruktor
     */
    public  EditPanel()
    {        
        addMouseMotionListener(ma);
        addMouseListener(ma);
        addMouseWheelListener(new ScaleHandler());
    } 
 
    /*
     * Zeichenmethode verschiedener Rechtecken
     */
    protected void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
     
        //wenn drawRect auf true gesetzt ist (was man mit dem Button IndividualForms tut) wird einen grauen Rect gezeichnet
        if(drawRect)
        {
            borderrect(g);
        }
        //wenn drawOrangeRect auf true gesetzt ist (was man mit dem Button OrangeForms tut) wird einen orangenen Rect gezeichnet
        if(drawOrangeRect)
        {
            filledrect(g);
        }
     
    }
 
    /* 
     * Erstellt ein Rechteckt mit grauem Rahmen
     */
    public void borderrect (Graphics g)
    {
        //FÜGE HIER DIE NEUE VARIABLE EIN
        Rectangle rec = new Rectangle2D.Float(0,0,100,100);
        Graphics2D g2d = (Graphics2D) g;
 
        g2d.setPaint(Color.LIGHT_GRAY);
        g2d.setStroke(new BasicStroke(2.0f));
        
        rectangles.add(rec);
      
        for (Rectangle2D r : rectangles) 
        {
            g2d.draw(r);
        }     
            
    }
    
    /* 
     * Erstellt ein orangenes Rechteckt
     */
    public void filledrect (Graphics g) 
    {       
        //FÜGE HIER DIE NEUE VARIABLE EIN
        Rectangle rec = new Rectangle2D.Float(0,0,100,100);
        Graphics2D g2d = (Graphics2D) g;
     
        g2d.setPaint(orangeRect);
  
        rectangles.add(rec);
         
        for (Rectangle2D r : rectangles) 
        {
            g2d.fill(r);
        }      
    }
    
    /*
     * Hier werden die Aktionen definiert, wie sich der erstellte Rechteck beim
     * Mausdraggen und Mausclicken verhält
     */
    class MovingAdapter extends MouseAdapter 
    {
        private int x;
        private int y;
 
        public void mousePressed(MouseEvent e) 
        {
            x = e.getX();
            y = e.getY();
        }
 
        public void mouseDragged(MouseEvent e) 
        {
            int dx = e.getX()-x;
            int dy = e.getY()-y;
 
            if (rec.getBounds2D().contains(x, y)) 
            {
                rec.x = rec.x + dx;
                rec.y = rec.y + dy;
                repaint();
            }
            x = x + dx;
            y = y + dy;
        }
    }
 
  
    /*
     * Hier werden die Aktionen definiert, wie sich der erstellte Rechteck beim
     * Scrollen mit der mittlere Taste verhält
     */
    class ScaleHandler implements MouseWheelListener 
    {
        public void mouseWheelMoved(MouseWheelEvent e) 
        {
            int x = e.getX();
            int y = e.getY();
 
            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) 
            {
                if (rec.getBounds2D().contains(x, y)) 
                {
                    float amount = e.getWheelRotation() * 5f;
                    rec.width = rec.width + amount;
                    rec.height = rec.height + amount;
                    repaint();
                }
            }
        }
    }
}
```

Auch könntest du die beiden Methoden, um ein Rechteck zu zeichnen,  in eine packen.

```
/* 
     * Erstellt ein Rechteckt
     */
    public void filledrect (Graphics g, Color color) 
    {       
        //FÜGE HIER DIE NEUE VARIABLE EIN
        Rectangle rec = new Rectangle2D.Float(0,0,100,100);
        Graphics2D g2d = (Graphics2D) g;
     
        g2d.setPaint(color);
  
        rectangles.add(rec);
         
        for (Rectangle2D r : rectangles) 
        {
            g2d.fill(r);
        }      
    }
```
Aufgerufen wird die Methode mittels

```
filledrect(g, grayRect); //GrauesRechteck
filledrect(g, orangeRect); //Oranges Rechteck
```


----------



## plammy (22. Jun 2012)

die idee mit der ersetzen von 2 methoden in eine finde ich klasse hat auch super geklappt  .. nur das problem ist immer noch dasgleiche ... der 2 rechteck wird genau über den ersten gezeichnet (egal wohin ich den ersten verschoben habe  )


----------



## Plopo (22. Jun 2012)

Hast du auch

```
Rectangle2D.Float rec = new Rectangle2D.Float(0,0,100,100);
```
als "Klassenvariable" entfernt und als Variable in die Methode gepackt?

Ansonsten poste nochmal deinen neuen Code.


----------



## plammy (22. Jun 2012)

ja aber dann funktionieren die mouselistener methoden nicht richtig.. es bewegt sich ganz laaaaaangsam und nur zu einer bestimmten position


----------



## Michael... (22. Jun 2012)

Deine Berechnung zu Bewegung der Rechtecke stimmt nicht - ausser die Verschiebung soll tatsächlich überproportional zur Mausbewegung passieren: Es wird jedes Mal das Rechteck um die absolute Bewegung seit dem Mausclick verschoben.
Und sollte das zu verschiebene Rechteck nicht eher bei MouseClicked als beim MouseDragged bestimmt werden - zu mindenst würde ich das als naiver Nutzer erwarten.


----------



## plammy (22. Jun 2012)

es kann doch nicht sein dass es nicht stimmt wenn das einwandsfrei funktionert .. es sei denn man packt rec in der methode...


----------



## SlaterB (22. Jun 2012)

'ja aber dann' heißt meistens, dass etwas falsch gebaut ist und nur durch ein anderes falsches Notkonstrukt künstlich am Leben gehalten wird,
das zählt nicht als sinnvolle Begründung,

was immer falsch läuft musst für sich untersucht und korrekt eingebaut werden,
wie hier schon vor einer Stunde gesagt wurde (und diesmal musste ich es nicht tun  ) geht es ohne Code nicht weiter

die Struktur muss sich bereits deutlich geändert haben,
vorher gab es ja auch 
> rectangles.add(rec);
was innerhalb der paint-Methode, die wer weiß wie oft durchgelaufen wird, auf jeden Fall schlimm war,
die Liste muss ja auf hunterte und mehr Elemente in kurzer Zeit angestiegen sein


----------



## Michael... (22. Jun 2012)

OK. hab gerade gesehen, dass der erfasst "Klickpunkt" beim verschieben auch erfasst wird.

Aber grundsätzlich ist der Aufbau und die Logik - meiner Meinung nach - falsch. Zumindest das was man von Deinem Code bisher im ersten Post gesehen hat.

In den gängigen Tools die ich kenne werden zu selektiernde/bewegende... Objekt beim Mausklick bestimmt und nicht während die Maus gezogen wird. Das Manipulieren der Liste in der halb der paint hat Slater ja bereits erwähnt.


----------



## Harry Kane (22. Jun 2012)

Wenn rec von einer Instanzvariablen zu einer lokalen Variablen in den borderrect oder fillrect Mehoden wird, sollte der gesamte Code nicht mehr kompilierbar sein, weil dann die rec Variablen in den MouseListener und MouseMotionListener Methoden nicht auffindbar sein sollten.
Ich stimme mit Michaels Meinung überein:
1. Definieren einer neuen Instanzvariablen selectedRect vom Type Rectangle2D.
2. Beim Klicken wird geprüft, ob die Koordinaten innerhalb eines Rechtecks liegen. Wenn ja, wird selectedRect auf das passende Rectangle2D gesetzt, ansonsten ist selectedRect null.
3. beim Draggen wird überprüft, ob selectedRect null ist. Falls nein, werden seine Koordinaten geändert.


----------



## plammy (25. Jun 2012)

Ja super danke hat geklappt  Jetzt kann ich 2 verschiedene typen von rechtecken zeichenen und die einzelnen selectieren und bewegen  nur ich will dass ich jedes mal wenn ich auf button 1 bzw button 2 einen neuen rechteck erstellt wird... das passiert nur 1x pro button.. ich habe mir gedacht vllt mit iterator?? bis klappt das nicht so 


```
public class EditPanel extends JPanel
{

    static  boolean drawRect = false;
    static  boolean drawOrangeRect = false;
    
    
    Rectangle2D.Float selectedRect;
    
 
    List<Rectangle2D.Float> rectangles = new ArrayList<>();
    List<Rectangle2D.Float> rectangles2 = new ArrayList<>();
 
    Rectangle2D.Float rec = new Rectangle2D.Float(0,0,100,100);
    Rectangle2D.Float rec2 = new Rectangle2D.Float(0,0,50,80);
    
 
    //Colors
    Color grayRect = new Color(230,227,224);
    Color orangeRect = new Color(211,111,53);

    MovingAdapter ma = new MovingAdapter();
      
    /*
     * Konstruktor
     */
    public  EditPanel()
    {  
        setPreferredSize(new Dimension(1200,2000));
        addMouseMotionListener(ma);
        addMouseListener(ma);
        addMouseWheelListener(new ScaleHandler());
      
    } 


    /*
     * Zeichenmethode verschiedener Rechtecken
     */
    protected void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
       
        //wenn drawRect auf true gesetzt ist (was man mit dem Button IndividualForms tut) wird einen grauen Rect gezeichnet
        if(drawRect)
        {     
            useIterator(rectangles);
            borderrect(g);   
        }
        //wenn drawOrangeRect auf true gesetzt ist (was man mit dem Button OrangeForms tut) wird einen orangenen Rect gezeichnet
        if(drawOrangeRect)
        {
            useIterator(rectangles2);
            filledrect(g);
        }
      
    }

      
 public void useIterator(ArrayList<Rectangle2D.Float> rectangles)
    {
        Iterator i = rectangles.iterator();
        while(i.hasNext())
        {
           rec=(Rectangle2D.Float)i.next();
        }
    }
      
    public void useIterator2(ArrayList<Rectangle2D.Float> rectangles2)
    {
        Iterator i2 = rectangles2.iterator();
        while(i2.hasNext())
        {
           rec2=(Rectangle2D.Float)i2.next();
        }
    }
   
 /* 
     * Erstellt ein Rechteckt mit grauem Rahmen, nachdem der User die Eingaben bausteinW (für Breite)
     * und bausteinH (für Höhe)
     */
    public void borderrect (Graphics g)
    {     

        Graphics2D g2d = (Graphics2D) g;

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        g2d.setPaint(Color.LIGHT_GRAY);
        g2d.setStroke(new BasicStroke(2.0f));

            rectangles.add(rec);
         
            for (Rectangle2D r : rectangles) 
            {
                g2d.draw(r);
            } 
         
        }

    
    /* 
     * Erstellt ein orangenes Rechteckt, nachdem der User die Eingaben bausteinOrangeW (für Breite)
     * und bausteinOrangeH (für Höhe)
     */
    public void filledrect (Graphics g) 
    {       
     
        Graphics2D g2d = (Graphics2D) g;
     
        g2d.setPaint(orangeRect);
        
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        
        rectangles2.add(rec2);
         
        for (Rectangle2D r : rectangles2) 
        {
            g2d.fill(r);
        } 
        
        
    }

    /*
     * Hier werden die Aktionen definiert, wie sich der erstellte Rechteck beim
     * Mausdraggen und Mausclicken verhält
     */
    class MovingAdapter extends MouseAdapter 
    {
        private int x;
        private int y;

        public void mousePressed(MouseEvent e) 
        {
            //liegen die Koordidanten inerhalb des Rectecks?
            //wenn ja sectedRect aud passende Rectnagle2D sentzte
            //else null
            
            x = e.getX();
            y = e.getY();
            
            if (rec.getBounds2D().contains(x, y)) 
                selectedRect=rec;
            
            if (rec2.getBounds2D().contains(x, y)) 
                selectedRect=rec2;
        }

        
        public void mouseDragged(MouseEvent e) 
        {
            int dx = e.getX()-x;
            int dy = e.getY()-y;
            
            if(selectedRect != null){
                selectedRect.x = selectedRect.x + dx;
                selectedRect.y = selectedRect.y + dy;
                repaint();
            }
            x = x + dx;
            y = y + dy;
        }
    }

  
    /*
     * Hier werden die Aktionen definiert, wie sich der erstellte Rechteck beim
     * Scrollen mit der mittlere Taste verhält
     */
    class ScaleHandler implements MouseWheelListener 
    {
        public void mouseWheelMoved(MouseWheelEvent e) 
        {
            int x = e.getX();
            int y = e.getY();

            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) 
            {
                if (rec.getBounds2D().contains(x, y)) 
                {
                    float amount = e.getWheelRotation() * 5f;
                    rec.width = rec.width + amount;
                    rec.height = rec.height + amount;
                    repaint();
                }
                if (rec2.getBounds2D().contains(x, y)) 
                {
                    float amount = e.getWheelRotation() * 5f;
                    rec2.width = rec2.width + amount;
                    rec2.height = rec2.height + amount;
                    repaint();
                }
            }
        }
    }

    
}
```


----------



## Michael... (25. Jun 2012)

Die Verwendung von Iterator ist falsch und das Vorgehen ist eher ungeschickt.

1. Es gibt eine Liste in der alle Rechtecke und sonstige zu zeichnenden Objekte gehalten werden
   (wenn man will kann man hier auch zwei getrennte Listen halten, aber wie es 
dann mit der Reihenfolge bei sich überlagernden Rechtecken - was wenn man irgendwann man 100 verschiedenartige Rechtecke/Objekte darstellen will...)
2. In der paintComponent wird einfach nur über diese Liste iteriert und die darin enthaltnen Objekte gezeichnet
3. Bei einem Buttonclick wird ein neues Rechteck/Objekt mit den gewünschten Attributen erstellt und in die Liste eingefügt. Anschließend wird ein repaint() an der darstellenden Komponente angefordert.


----------



## plammy (25. Jun 2012)

unter in liste iterieren versteh ich aber iterator ?!?


----------



## SlaterB (25. Jun 2012)

im ganzen Code ist kein ActionListener zu sehen, dazu kann kaum was gesagt werden,

zu Iterator gibts aber viel zu meckern,
was sollen die Methoden useIterator/ useIterator2? 
sie haben kein effekt, außer z.b. am Ende rec auf das letzte Element der Liste rectangles zu setzen,
wenn das dein Ziel ist, mache das doch auf humane Weise (auch wenn leider der Java-Befehl dazu kryptisch ist):
> rec = liste.get(liste.size()-1);

vermeidbar schlecht ist daran nebenbei, die Liste rectangles als Parameter zu übergeben, obwohl die Methode doch selber
alle Instanzattribute kennt?, 
den Parameter auch noch den gleichen Namen zu geben macht es noch unnötiger

an 
> /* GIBT KEIN FEHLER AUS ABER TUT AUCH NIX  */
hast du schon wieder Iterator, aber i wird dort nicht neu gesetzt, ist auch sonst nirgendwo als Instanzattribut zu sehen,
ist wahrscheinlich 'alle', irgendwann mal durchlaufen, 
Iteraoren werden vor Verwendung normalerweise neu angefordert, so wie in useIterator() zu sehen

> rectangles.add(rec);
in den paint-Methoden ist weiterhin schwerstens zu bemängeln, in paint soll gezeichnet, keine Listen befüllt werden,
kannst du begründen was du dazu vorhast? 
gut, auf 'irgendwas anderes geht sonst nicht' kann in der Tat verzichtet werden, 
beliebige Befehle aneinanderreihen, so dass zufällig funktionierende Zwischenstände herauskommen..

---------

> die idee mit der ersetzen von 2 methoden in eine finde ich klasse hat auch super geklappt

hast du früher geschrieben, nun sind aber wieder borderrect/ filledrect  einzeln vorhanden?
wahrscheinlich aus denselben Grund


----------



## bERt0r (25. Jun 2012)

Lol. Dann also basics, Deutsch: Iterator steht zwar nicht im Duden, die Großschreibung lässt einen aber erahnen dass es ein Nomen (Hauptwort ist) während iterieren ein Verb (Zeitwort ist. Der Unterschied zwischen einem Nomen und einem Verb: Nomen bezeichnen Dinge oder Personen, Verben Tätigkeiten.
Zur Bedeutung:
Duden | iterieren | Bedeutung, Rechtschreibung und Duden | Iteration | Bedeutung, Rechtschreibung, Grammatik, Herkunft
Ein Iterator heißt Iterator, weil er dir ermöglicht über eine Collection zu iterieren. Das bedeutet, die gleiche Anweisung wiederholt auf alle Elemente einer Collection anzuwenden.
Was du hier machst ist alle Elemente der Collection einmal anzuschaun, du führst aber keine Anweisung durch. 

```
Iterator i = rectangles.iterator();
        while(i.hasNext())
        {
           rec=(Rectangle2D.Float)i.next();
        }
```
Bevor du irgendeinen Coder schreibst oder von wo rauskopierst, finde mal raus was der Code macht und wieso er das macht was er tut. Dein Vorgehen hier kann man so beschreiben: du hast einen Satz Plakate und willst sie auf eine Leinwand kleben. Also nimmst du das erste in die Hand, dann setzt aber anscheinend dein Hirn aus und du nimmst das 2. in die Hand, usw. Am Schluss hattest du jedes Platkat mal in der Hand, auf der Leinwand ist aber keins gelandet und jetzt wunderst du dich wieso. Irgendwas hast du doch vergessen


----------



## plammy (25. Jun 2012)

ich hab auch schon so versucht 


```
Iterator i = rectangles.iterator();
        while(i.hasNext())
        {
           rec=(Rectangle)i.next();
           rectangles.add(rec);
         }
```


also die gefundene Rechtecke hinzuzufügen nacheinader klappt aber nicht


----------



## SlaterB (25. Jun 2012)

dieser Code für sich wäre in jedem Programm der Welt falsch, 
er ist in sich bestenfalls sinnlos, genauer sogar schädlich auf verschiedene Weisen,

wann fängst du an, in Worten zu beschreiben was du möchtest, statt Code zu posten aus denen niemand raten kann, was er soll?


> also die gefundene Rechtecke hinzuzufügen nacheinader klappt aber nicht 
oh, war der Satz schon immer da? 
was sind 'gefundene Rechtecke', wo hinzufügen? genau in dieselbe Liste ist doch nicht gerade logisch?


----------



## Michael... (25. Jun 2012)

plammy hat gesagt.:


> unter in liste iterieren versteh ich aber iterator ?!?


das "falsch" bezog sich auf den ursprünglichen Code. Im editierten Code wird ja korrekt - allerdings wirkungslos - iteriert.

Es scheint als ist Dir das Zeichnenkonzept in Swing nicht ganz klar zu sein. Innerhalb der paintComponent wird nach Möglichkeit nur gezeichnet oftmals wir dabei der ganze Inhalt neu aufgebaut.
Das Bereitstellen der Daten (Erzeugen von Rechtecken, Hinzufügen zu Listen...) erfolgt ausserhalb dieser Methode.

Den zuletztgeposteten Code hat Slater ja schon kommentiert.


----------



## plammy (25. Jun 2012)

@ Michael

Mit in der Liste iteragieren meinst vllt so??:


```
public void borderrect (Graphics g)
    {     
        
        Graphics2D g2d = (Graphics2D) g;

            rectangles.add(rec);
              
            for (int i = 0; i < rectangles.size(); i++) {
            rec = (Rectangle)rectangles.get(i);
            
                g2d.setColor(grayRect);
                g2d.fill(rec);
                g2d.setColor(border);
                g2d.draw(rec);
            }
          
        }
```


----------



## SlaterB (25. Jun 2012)

bis auf Zeile 6 ein erfreulich klarer Code, wie man sich ihn nur wünschen kann,
falls ich mich weiter einmischen darf

das add() muss weiter kontrolliert außerhalb stattfinden, etwa beim Button-Klick, der das neue rec anlegt


----------



## plammy (25. Jun 2012)

SlaterB hat gesagt.:


> etwa beim Button-Klick




```
protected void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
        
        Graphics2D g2d = (Graphics2D) g;
//wenn drawRect auf true gesetzt ist (was man mit dem Button IndividualForms tut) wird einen grauen Rect gezeichnet
        if(drawRect)
        {  
            rectangles.add(rec);   //HIER ??? Hmm es zeichnet dennoch nicht :(
            borderrect(g);
            
        }   
       
        //wenn drawOrangeRect auf true gesetzt ist (was man mit dem Button OrangeForms tut) wird einen orangenen Rect gezeichnet
        if(drawOrangeRect)
        {
            filledrect(g);
        }

    }
```


----------



## SlaterB (25. Jun 2012)

der gepostete Code ist immer noch eine paint-Methode, kein Button

und wie so oft:
erwarte nicht dass ein einzelner Befehl irgendwo dazu oder weniger auf einmal alles richtig werden läßt,
das Programm besteht auf 200 Zeilen, von denen jede wichtig ist,

für den Anfang wäre schon toll, erstmal den ActionListener im Programm zu finden (!, seit Tagen ein Thema, von Button postest du NIE etwas)
und dort System.out.println()-Ausgaben einzubauen
"bisher waren .. Rectangles bekannt"
"nun gibt es .. Rectangles"

in paint vielleicht noch
"male .. Rectangles"
ohne dass es gleich funktionieren muss

schon so einfache Ausgaben wären ein Erfolg,
System.out.println() lernt man im ersten Hello World-Programm
und ist viel wichtiger als 1000 Zeilen GUI-Geschnösel


----------



## plammy (25. Jun 2012)

Ja der Button ist in einer anderen Klasse "CreateFile".. Beim Drücken der Button setze ich eine variable auf true.. so kann ich später sagen (in der paintComponent Methode) wenn die diese Variable auf true gesetzt wurde zeichen rec.


```
public class CreateFile extends JPanel implements ActionListener
{


      public CreateFile()
    {

        initComponents();        
    }

    
    public void initComponents() 
    {
        buttonIndividualForms = new JButton();
        buttonOrangeForms = new JButton();

        buttonIndividualForms.setText("erstellen");
        buttonIndividualForms.addActionListener(this);
       
        
        buttonOrangeForms.setText("erstellen");
        buttonOrangeForms.addActionListener(this);
      
}


    @Override
    public void actionPerformed(ActionEvent object) 
    {
 if (object.getSource() == buttonIndividualForms)
        {    
  
            EditPanel.drawRect=true;

            
        } 
        if (object.getSource() == buttonOrangeForms)
        {    

            EditPanel.drawOrangeRect=true;

        } 

    }
```


----------



## SlaterB (25. Jun 2012)

das kommt mir ja von früher bekannt vor, zum Umschalten von einer Art der Darstellung auf eine andere wäre das denkbar,
aber was bringt dich dazu, dass dann paint ein rec in eine Liste einfügt?

entweder müssen genau diese Button hier das Objekt erstellen und adden, wenn das hier schon geeignet erscheint,
oder das passiert zu einem anderen fest definierten Zeitpunkt


----------



## plammy (25. Jun 2012)

> entweder müssen genau diese Button hier das Objekt erstellen und adden,


ähm der Satz versteh ich nicht ganz


----------



## SlaterB (25. Jun 2012)

"rec in eine Liste einzufügen" ist bei dir irgendwie ein Thema, wenn auch noch nie von dir in Worte gefasst/ irgendwie erklärt,

diese Aktion, einmal mehr wiederholt, darf wie alle zustandsändernden Aktionen nicht in paint passieren, 
denn paint ist vollkommen unkontrolliert, in einer sec kann 100x paint ausgeführt werden oder auch gar nicht, 
davon darf das Programm nicht abhängen

diese Aktion, wenn überhaupt irgendwo irgendwann zu unbekannten Zwecke nötig, kann hier gleich im ActionListener passieren
oder später zu einem bestimmten Zeitpunkt, etwa bei einen anderen Buttonklick, vielleicht wenn das nächste Rectangle kommt,
und das vorherige noch zur Bearbeitung offen bleibt

für den zuletzt genannten Fall wäre es z.B. denkbar, dass die paint-Methode sich eine eigene temporäre rec-Liste erstellt 
und dort alle aus der alten Liste kopiert, sowie noch rec mit hinein,
so überlegt durchgeführt könnte manche deiner bisherigen Codes Sinn ergeben


----------



## plammy (25. Jun 2012)

> z.B. denkbar, dass die paint-Methode sich eine eigene temporäre rec-Liste erstellt



wie noch eine?
bzw . was ist mit einer temporäre Liste gemeint?


----------



## SlaterB (25. Jun 2012)

eine Liste die nicht permanent, sondern nur kurzzeitig besteht,
aber ich werde nun wahrlich auch noch mögliche Zwecke dafür aufzählen,
du bist es der die ganze Zeit mit Listen hantierst, wobei vielleicht nur auf Vorschläge anderer hin,

wovon rede ich überhaupt die ganze Zeit, stelle doch nochmal eine aktuelle Frage


----------



## Harry Kane (26. Jun 2012)

Hier ein Codeschnipsel, um folgendes zu zeigen:
1. Wie wird ein flag oder eine andere Eigenschaft mit Hilfe einer GUI an ein Objekt übertragen, ohne diese hässlichen statischen Variablen zu verwenden.
2. Wie wird dynamisch die preferred size berechnet.
3. Was soll in paintComponent gemacht werden.
Ansonsten fällt mir kein weiterer Kommentar ein.

```
public class DrawBoard implements ActionListener{
    private JTextField xText = new JTextField(3);
    private JTextField yText = new JTextField(3);
    private JTextField wText = new JTextField(3);
    private JTextField hText = new JTextField(3);
    private JCheckBox filled = new JCheckBox("Filled");
    private JButton createButton = new JButton("Create");
    private DrawPanel dp;

    public static void main(String[] args){
        DrawBoard db = new DrawBoard("Edit Panel");
    }

    public DrawBoard(String titel) {
        JFrame frame = new JFrame(titel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel editPanel = new JPanel();
        editPanel.add(new JLabel("x"));
        editPanel.add(xText);
        editPanel.add(new JLabel("y"));
        editPanel.add(yText);
        editPanel.add(new JLabel("w"));
        editPanel.add(wText);
        editPanel.add(new JLabel("h"));
        editPanel.add(hText);
        editPanel.add(createButton);
        editPanel.add(filled);
        createButton.addActionListener(this);
        filled.addActionListener(this);
        frame.getContentPane().add(editPanel, BorderLayout.NORTH);
        dp = new DrawPanel();
        dp.addRectangle(new Rectangle(0, 0, 100, 100));
        dp.addRectangle(new Rectangle(50, 50, 60, 60));
        dp.addRectangle(new Rectangle(150, 150, 20, 20));
        frame.getContentPane().add(dp);
        frame.pack();
        frame.setVisible(true);
    }
    public void actionPerformed(ActionEvent ae){
        if(ae.getSource() == createButton){
            try{
                int x = Integer.parseInt(xText.getText());
                int y = Integer.parseInt(yText.getText());
                int w = Integer.parseInt(wText.getText());
                int h = Integer.parseInt(hText.getText());
                dp.addRectangle(new Rectangle(x, y, w, h));
            }
            catch(NumberFormatException e){
                e.printStackTrace();
            }
        }
        if(ae.getSource() == filled){
            dp.setRectsFilled(filled.isSelected());
        }
    }
}

class DrawPanel extends JPanel{
    private Rectangle selected;

    private Dimension preferredSize = new Dimension(0, 0);

    private MovingAdapter ma = new MovingAdapter();

    private ArrayList<Rectangle> rects = new ArrayList<Rectangle>();

    private boolean rectsFilled;

    public DrawPanel(){
        super();
        addMouseListener(ma);
        addMouseMotionListener(ma);
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setPaint(Color.RED);
        for(Shape shape: rects){
            if(rectsFilled){
                g2.fill(shape);
            }
            else{
                g2.draw(shape);
            }
        }
    }

    public Dimension getPreferredSize(){
        return preferredSize;
    }

    public void addRectangle(Rectangle rect){
        rects.add(rect);
        calculateSize();
        Window window = SwingUtilities.getWindowAncestor(this);
        if(window != null) window.pack();
        repaint();
    }
    public void setRectsFilled(boolean flag){
        this.rectsFilled = flag;
        repaint();
    }
    private void calculateSize(){
        if(rects.size() < 1) return;
        int xMax = 0;
        int yMax = 0;
        for(Rectangle rect: rects){
            xMax = Math.max(xMax, rect.x + rect.width);
            yMax = Math.max(yMax, rect.y + rect.height);
        }
        preferredSize.width = xMax + 2;
        preferredSize.height = yMax + 2;

    }
    class MovingAdapter extends MouseAdapter {

        private int x;
        private int y;

        public void mousePressed(MouseEvent e) {
            x = e.getX();
            y = e.getY();
            selected = null;
            for(int i = rects.size() - 1; i >= 0; i--){
                if(rects.get(i).contains(x, y)){
                    selected = rects.get(i);
                    break;
                }
            }
        }

        public void mouseDragged(MouseEvent e) {
            if(selected == null) return;
            int dx = e.getX() - x;
            int dy = e.getY() - y;

            selected.x = selected.x + dx;
            selected.y = selected.y + dy;
            repaint();
            x = x + dx;
            y = y + dy;
        }
    }
}
```


----------



## plammy (2. Jul 2012)

@Harry Kane: Super vielen Dank  Klappt jetzt prima


----------

