# AWT bestimmte Objekte zeichnen und löschen



## 4nubis (8. Sep 2011)

Hi,

ich möchte ein Programm schreiben, mit dem es möglich ist Objekte zu zeichnen und bestimmte Objekte zu löschen. Also wenn durch den klick auf der Zeichenfläche der Umfang des Objektes berührt wurde und man dann auf den Button Löschen One klickt auch nur dieser oder auch alle anderen dadurch berührt werden gelöscht werden. Alles kann man ja mit repaint löschen, jedoch bekomme ich das mit einzelnen Objekten nicht hin. Ich habe bereits sehr lange im Web gesucht, jedoch habe ich nix gefunden. Kann natürlich auch sein, dass ich nach dem falschen gesucht habe -.-.

Vielen Dank


```
import java.awt.*;
import java.awt.event.*;
import java.applet.*;


public class draw extends Applet implements ItemListener,ActionListener {

	
	int breite;
	
	public TextField Breite;
	public Button Löschen_All, Löschen_one;
	public Choice Objekt;
	public Label label_breite;
	
	
	public void actionPerformed(ActionEvent e) {
	    if (e.getActionCommand().equals("Löschen All")){
	    	repaint();}
	}
	
public void init  () {
		
		breite= 200;
	
		Breite = new TextField ("200");
		label_breite = new Label ("Breite");
	
		Löschen_All = new Button ("Löschen All");
		Löschen_All.addActionListener(this);
		Löschen_one = new Button ("Löschen One");
		Löschen_one.addActionListener(this);
		
		Objekt = new Choice();
		Objekt.add("Kreis");
		Objekt.addItemListener(this);

		
        Panel steuerung  =new Panel(); 
        steuerung.add(label_breite);
        steuerung.add(Breite);
        steuerung.add (Objekt);
        steuerung.add (new Label());
        steuerung.add (Löschen_All);
        steuerung.add (Löschen_one);
    	
        
    	setLayout(null );
    	setSize(900,700);
    	
        add(steuerung);
        steuerung.setLayout(new GridLayout(20,20));
        steuerung.setSize(200,700);
    	setBackground(Color.BLUE);
    	

        addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent e)
            {
            	Graphics g = ((draw) e.getSource()).getGraphics();
              
                 int x = e.getX();
                 int y = e.getY();
               
                 breite = Integer.parseInt(Breite.getText());
                         
                 switch (Objekt.getSelectedIndex())
                 {
                      case 0:
              	
          				g.drawOval (x, y, breite, breite);
                    	; 
                    	break;
            }
     } 

});
}
       	      public void mouseReleased(MouseEvent e) {}
    	      public void windowActivated(WindowEvent e) {}
    	      public void windowClosed(WindowEvent e) {
    	        
    	      }
    	      public void windowClosing(WindowEvent e) {
    	        System.exit(0);
    	      }
    	      public void windowDeactivated(WindowEvent e) {}
    	      public void windowDeiconified(WindowEvent e) {}
    	      public void windowIconified(WindowEvent e) {}
    	      public void windowOpened(WindowEvent e) {}
    	      public void itemStateChanged(ItemEvent e) {
				
			}

}
```


----------



## c_sidi90 (8. Sep 2011)

Wie speicherst du die einzelnen Objekte denn? In einer Arraylist? Du solltest den einzelnen Objekten X und Y Koordinaten mitgeben. Eine Möglichkeit die Collision abzufragen wäre, die Objekte von einem Rectangle einschliessen zu lassen, welche du aus den Attributen x,y, Höhe und Breite des Zeichenobjektes erstellst. Wenn das Mouseevent aufgerufen wird, erstellst du mit den event.getX und Y Koordinaten ein Curserrectangle und prüfst ob dieses mit einem Objektrectangle aus der Arraylist in berührung kommt.

Im Anschluss nurnoch abfragen an welcher Position dieses Zeichenobjekt in der Liste steht und diesen Eintrag entfernen. 

Lg


----------



## bERt0r (8. Sep 2011)

Du hast da den falschen Ansatz. Gezeichnet werden sollte nur in der paint/paintComponent Funktion.  Ich nehme mal an, sobald du die größe deines Fensters veränderst verschwindet auch alles.
Ein besserer Ansatz wäre, du machst dir Klassen für deine Formen, speicherst die in einer Collection und in der paintComponent Methode arbeitest du die Collection durch und zeichnest jedes Objekt.
Deine Formen können glaube ich von JComponent erben, mit setOpaque kannst du sie durchsichtig machen. Dadurch solltest du über contains(x,y) herausfinden können, ob ein bestimmter Punkt innerhalb einer Form liegt.
Sobald du eine Form löschen willst, entfernst du sie einfach aus deiner Collection und machst repaint()


----------



## 4nubis (9. Sep 2011)

Vielen Dank an euch beiden,ich werde versuchen eure Vorschläge in der Tat umzusetzen.


----------



## 4nubis (19. Sep 2011)

Hi,

ich brauche wieder eure Hilfe . Es geht darum, dass ein Feld sich pro Mausklick selbst aufzählt. Ich möchte somit erreichen, dass das vorher gezeichnete Objekt stehen bleibt und man dann ein Neues Objekt mit einem anderen Namen erzeugt. Habe es schon versucht, jedoch gibt er den X und Y Wert steht an allen.

Vielen Dank


```
package MyApplet;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

public class MyApplet extends Applet implements MouseListener {
	int x,y,b,h;

	Kreis k1, k2, k3,k4,k5;
	
        public void init() {
	    addMouseListener(this);
        }
     
        public void mousePressed(MouseEvent event){
    		
        	b=100;
    		h=100;
    		
    		Kreis[] kreise = new Kreis[4];
    		int i=0;
    		
    		while( i==0){
    			
    			x = event.getX();
        		y = event.getY();
        		kreise[i]= new Kreis(x,y,30,30,Color.RED); 
        		k1 = kreise[i];
        		if(x!=0){
    				i++;	
 
    			}  		

    		}
    		x=19;
    		y=4;
            while( i==1){
    			
    			x = event.getX();
        		y = event.getY();
        		kreise[i]= new Kreis(x,y,30,30,Color.RED); 
        		k2 = kreise[i];
        		if(x!=0){
    				i++;	
    	
    			}  		

    		}
            while( i==2){
    			
    			x = event.getX();
        		y = event.getY();
        		kreise[i]= new Kreis(x,y,30,30,Color.RED); 
        		k3 = kreise[i];
        		if(x!=0){
    				i++;	
    	
    			}  		

    		}

    		repaint();
    		System.out.println("eins  " + k1+" "+x);
    		System.out.println("drei   " + k3+" "+x);
    	}
	

	public void mouseEntered(MouseEvent event){ }
	public void mouseExited(MouseEvent event){ } 
	public void mouseReleased(MouseEvent event){}
	public void mouseClicked(MouseEvent e) {}

	
	public void paint(Graphics g) {
		k1.paint(g);
		k2.paint(g);
		k3.paint(g);

	}
	
}
```


----------



## Michael... (19. Sep 2011)

4nubis hat gesagt.:


> Es geht darum, dass ein Feld sich pro Mausklick selbst aufzählt. ...jedoch gibt er den X und Y Wert steht an allen.


Ich hab eine Vermutung was damit gemeint ist, bin mir aber nicht ganz sicher. Daher erkläre ich erst einmal was Dein Code macht:
Bei jeden Mausklick auf das Applet wird ein Array für vier Kreise erstellt. Drei "Plätze" davon, werden mit Kreisen der selben Postion und Größe belegt und den Varialben k1, k2, k3 zu gewiesen. Beim anschließenden Neuzeichnen werden diese drei Kreis - Objekte gezeichnet. Wobei man nur den letzten sieht, da er die zuvor gezeichneten Objekt übermalt.
Du willst aber vermutlich bei jedem Mausklick *ein* neues Kreis Objekt erzeugen und dieses an ein Array oder eine Liste (wäre besser) übergeben, um beim anschließenden Neuzeichnen alle Objekte zu zeichnen!?

Dazu benötigt Dein Applet ein Array/Liste als Instanzvariable (deren Geltungsbereich in der gesammten Klasse liegt) und in der mousePressed(...) wird einfach nur ein neues Kreis Objekt erzeugt und in diese Liste gesteckt.


----------



## bERt0r (19. Sep 2011)

Schau dir mal das Zeichnen in Swing Tutorial an. Du machst da einige Anfängerfehler, die darin ganz gut beschrieben werden.


----------



## 4nubis (19. Sep 2011)

Michael... hat gesagt.:


> Du willst aber vermutlich bei jedem Mausklick *ein* neues Kreis Objekt erzeugen und dieses an ein Array oder eine Liste (wäre besser) übergeben, um beim anschließenden Neuzeichnen alle Objekte zu zeichnen!?
> 
> Dazu benötigt Dein Applet ein Array/Liste als Instanzvariable (deren Geltungsbereich in der gesammten Klasse liegt) und in der mousePressed(...) wird einfach nur ein neues Kreis Objekt erzeugt und in diese Liste gesteckt.



Genau das habe ich vor . Aber ich bekomme es einfach nicht hin. Konntest du es mir evtl. an einem Beispielcode erklären?


@bERt0r

Danke für den Link gucke es mir gerade an


----------



## bERt0r (19. Sep 2011)

Ich hab dir ein Beispiel gemacht:
Du brauchst einen Behälter, um deine Formen zu speichern

```
class ColoredShape		//Mein Form-Objekt
	{
		Shape shape;
		Color color;
		boolean filled;
		int clickCount=0;
	}
```
Und dann noch eine Collection, wo du die verschiedenen Behälter aufbewahrst.

```
Vector<ColoredShape> shapes=new Vector<ColoredShape>();
```
Und dann noch einen Component, der das ganze zeichnet - du überschreibst die paintComponent Funktion:

```
public void paintComponent(Graphics graph)
			{
				Graphics2D g=(Graphics2D)graph;
				for(ColoredShape cs:shapes)			//Das hier das wesentliche, die Formen in der Collection werden gezeichnet
				{
					g.setColor(cs.getColor());
					if(cs.isFilled())
					{
						g.fill(cs.getShape());
					}
					else
					{
						g.draw(cs.getShape());
					}
					Rectangle2D bounds=cs.getShape().getBounds2D();
					float x=(float) (bounds.getX()+(bounds.getWidth()/2));
					float y=(float) (bounds.getY()+(bounds.getHeight()/2));
					g.setColor(Color.BLACK);
					g.drawString(String.valueOf(cs.getClicks()), x, y);
				}
}
```
Wenn sich irgendwas ändert, rufst du paintPane.repaint() auf *NICHT *paint oder paintComponent direkt.
Und hier das ganze noch als ausführbares Beispiel:


----------

