KreisZeichner

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
In folgendem Beispiel werden Kreise (Mittelpunkt: MousePressed; Rand: MouseReleased) auf ein JPanel gezeichnet.
Diese werden in einer Liste gespeichert.
Nun sollen die Kreise für die weitere Verwendung per Rechtsklick einzeln ausgewählt werden.
Wie ich rausfinde ob die linke oder rechte Maustaste gedrückt wurde, das hab ich ja mittlerweile raus gefunden.
Ebenso der Punkt an dem gedrückt wurde.
Aber wie kann ich einen so "angewählten" Kreis ansprechen?

Code:
import java.awt.Color;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;

public class GrafikObjekt
{
	Shape shape;
	Color color;


	GrafikObjekt(Shape se)
	{
		shape=se;
	}		
}
-----------------------------------------------------------------------
import java.util.ArrayList;
import javax.swing.JFrame;

/**
 * Ein Kreiseditor verknüpft alle Objekte sinnvoll miteinander.
 */
public class KreisEditor 
{
	public static void main(String[] args) 
	{
		ArrayList<GrafikObjekt> ll=new ArrayList<GrafikObjekt>();
		ZeichenPanel zp=new ZeichenPanel(ll);
		KreisZeichner kz=new KreisZeichner(zp,ll);
		zp.addMouseListener(kz);
		
		JFrame jf=new JFrame();
		jf.add(zp);
		jf.pack();
		jf.setVisible(true);
	}
}
------------------------------------------------------------------------
import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;

/**Ein KreisZeichner erstellt einen Kreis mit dem Radius, der zwischen den 
 * beiden Punkten entsteht, an denen die Maus gedrückt und losgelassen wird.
 * Den Kreis wird in einem GrafikObjekt abgespeichert und das widerum in einem 
 * ArrayList-Objekt.
 * Der KreisZeichner erhält bei seiner Erzeugung ein ArrayList-Objekt und 
 * speichert es als seine Eigenschaft.
 */
public class KreisZeichner extends MouseAdapter
{
	private Point mittelpunkt=new Point();
	private Point startpunkt=new Point();
	Ellipse2D.Double kreis;
	ArrayList<GrafikObjekt> ll;
	ZeichenPanel view;
	
	//Hier werden alle Kreise gespeichert:
	public KreisZeichner(ZeichenPanel view,ArrayList<GrafikObjekt> ll)
	{
		this.ll=ll;
		this.view=view;
	}
	
	//Wird die Maus gedrückt, merkt sich der KreisZeichner die Position:
	public void mousePressed(MouseEvent e) 
	{
		mittelpunkt=e.getPoint();
	}

	/**Wird die Maus losgelassen, berechnet der KreisZeichner die direkte 
	 * Entfernung, die die Maus zurückgelegt hat. Diese Entfernung wird einem 
	 * Ellipse2D Objekt als Parameter mitgegeben, das beim Ausführen dieser Methode 
	 * erschaffen wird. Dieses wird dann in einem GrafikObjekt gespeichert, welches 
	 * der ArrayList angehängt wird.
	 */
	public void mouseReleased(MouseEvent e) 
	{
		double r=e.getPoint().distance(mittelpunkt);
		startpunkt.x=mittelpunkt.x-(int)r;
		startpunkt.y=mittelpunkt.y-(int)r;
		Ellipse2D.Double kreis=new Ellipse2D.Double(startpunkt.x, startpunkt.y, 2*r, 2*r);
		GrafikObjekt go=new GrafikObjekt(kreis);
		
		//Hier wird dir Farbe der Kreise fest gelegt; HIER per Zufall:
		Color color=new Color((float)Math.random(),(float)Math.random(),(float)Math.random());
		go.color=color;
		
		ll.add(go);
		view.repaint();
	}
	
	public void mouseClicked(MouseEvent e) 
	{
		e.getButton();
		e.getPoint();
		System.out.println(e);
		
	}
}
----------------------------------------------------------------------------------------
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JPanel;

/**
 * Ein ZeichenPanel ist ein JPanel, das mehrere Kreise zeichnen kann.
 */
class ZeichenPanel extends JPanel
{
	ArrayList<GrafikObjekt> ll;
	
	/**Ein ZeichenPanel wird mit einer Größe von (700,500) erschaffen 
	 * und speichert die ihm übergebene ArrayList als Eigenschaft ab.
	 * @param ll Hier sind alle Kreise gespeichert.
	 */
	ZeichenPanel(ArrayList<GrafikObjekt> ll)
	{
		this.ll=ll;
		setPreferredSize(new Dimension(700,500));
	}
	
	/**Soll sich ein ZeichenPanel zeichnen, zeichnet erst einmal das JPanel 
	 * und dann werden alle in der ArrayList gespeicherten Kreise gezeichnet.
	 */
	public void paint(Graphics g)
	{
		Graphics2D g2=(Graphics2D)g;
		super.paint(g2);
		
		RenderingHints hints=new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.addRenderingHints(hints);
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
		
		//Hier werden Strichbreite,- und Art der Kreise fest gelegt:
		//BasicStroke bsGestrichelt=new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 1, new float[]{20},0);
		BasicStroke bs=new BasicStroke(1);
		g2.setStroke(bs);
		
		//Die Kreise werden mittels einer For(Each)-Schleife gezeichnet:
		for(GrafikObjekt t:ll)
		{
			g2.setColor(t.color);
			g2.draw(t.shape);
		}
	}
}
 
S

SlaterB

Gast
die Liste aller Kreise durchlaufen und die Position vergleichen,
wenn Kreise überlappen, dann diese Reihenfolge berücksichtigen
 
G

Gast

Gast
Hab das jetzt versucht (mit contains) aber irgendwie zeichnet er jetzt GAR KEINE Kreise mehr und ich check nicht woran es liegt...
...geschweige denn dass er meine AffineTransformation anwendet, wenn ich mit recht einen Kreis anklicke... :(

Hier noch mal die Klasse mit den wichtigsten Veränderungen, der KreisZeichner:

Code:
import java.awt.Color;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;

/**Ein KreisZeichner erstellt einen Kreis mit dem Radius, der zwischen den 
 * beiden Punkten entsteht, an denen die Maus gedrückt und losgelassen wird.
 * Den Kreis wird in einem GrafikObjekt abgespeichert und das widerum in einem 
 * ArrayList-Objekt.
 * Der KreisZeichner erhält bei seiner Erzeugung ein ArrayList-Objekt und 
 * speichert es als seine Eigenschaft.
 */
public class KreisZeichner extends MouseAdapter
{
	int kreisZähler=0;
	private Point mittelpunkt=new Point();
	private Point startpunkt=new Point();
	Ellipse2D.Double kreis;
	GrafikObjekt go=new GrafikObjekt(kreis);
	Shape alterKreis;
	Shape neuerKreis;
	ArrayList<GrafikObjekt> ll;
	ZeichenPanel view;
	AffineTransform at;
	
	
	//Hier werden alle Kreise gespeichert:
	public KreisZeichner(ZeichenPanel view,ArrayList<GrafikObjekt> ll)
	{
		this.ll=ll;
		this.view=view;
		
		//Das Lesezeichen für die Objekte (vergleichbar mit einem Index):
		//Iterator i=ll.iterator();
	}
	
	//Wird die Maus gedrückt, merkt sich der KreisZeichner die Position:
	public void mousePressed(MouseEvent e) 
	{
		mittelpunkt=e.getPoint();
	}

	/**Wird die Maus losgelassen, berechnet der KreisZeichner die direkte 
	 * Entfernung, die die Maus zurückgelegt hat. Diese Entfernung wird einem 
	 * Ellipse2D Objekt als Parameter mitgegeben, das beim Ausführen dieser Methode 
	 * erschaffen wird. Dieses wird dann in einem GrafikObjekt gespeichert, welches 
	 * der ArrayList angehängt wird.
	 */
	public void mouseReleased(MouseEvent e, AffineTransform at) 
	{
		//Die Anzahl der Kreise soll herausgefunden werden:
		e.getButton();
		
		/**Nur wenn die linke Maustaste gedrückt wird, wird ein Kreis gezeichnet
		 * und der Kreiszähler um eins hochgezählt:
		 */
		if (e.getButton()==1)
		{
			kreisZähler++;
			System.out.println(kreisZähler); 
			double r=e.getPoint().distance(mittelpunkt);
			startpunkt.x=mittelpunkt.x-(int)r;
			startpunkt.y=mittelpunkt.y-(int)r;
			Ellipse2D.Double kreis=new Ellipse2D.Double(startpunkt.x, startpunkt.y, 2*r, 2*r);
			GrafikObjekt go=new GrafikObjekt(kreis); //Damit haben wir einen noch nicht transformierten Kreis geschaffen!
			
			//Hier wird dir Farbe der Kreise fest gelegt; HIER per Zufall:
			Color color=new Color((float)Math.random(),(float)Math.random(),(float)Math.random());
			go.color=color;
		
			//Der Kreis wird der ArrayList hinzugefügt:
			ll.add(go);
			
			view.repaint();
		}
	}
	
	public void mouseClicked(MouseEvent e) 
	{
		//Die AffineTransform, die auf den Kreis angewandt werden soll wird geholt:
		at=go.getAt();
		
		//Es soll herausgefunden werden welche Maustaste gedrückt wurde:
		e.getButton();
	
		/**Wenn mit der rechten Maustaste in JPanel geklickt wird soll
		 * herausgefunden werden wo, und ob ein Kreis dabei gewählt wurde
		 * und wenn ja, soll er transformiert werden:
		 */
		if (e.getButton()==3)
		{
			e.getPoint();
			for(GrafikObjekt go: ll)
			{
				if(go.getShape().contains(e.getPoint()))
				{
					neuerKreis=go.setShape(at.createTransformedShape(alterKreis));
					//go.setShape(neuerKreis);
					ll.add(go);
				}
			}
		}
	}
}
 
G

Gast

Gast
So, jetzt werden die Kreise wieder gezeichnet, allerdings wird die Affine Transformation nicht auf den Kreis angewandt, wenn er mit der rechten Maustaste angeklickt wird...
Vielleicht kann mir jmd. einen Tip geben was ich in der MausClicked()-Methode verändern muss, damit sie auf einen Rechtsklick, sofern dieser auf dem Kreis (Component) liegt bewirkt, dass dieser (Kreis) transformiert wird.

Die Affine Transformation, die bei mir auf den Kreis angewandt werden soll ist (erstmal) nur eine Verschiebung (Translation), wie man sieht...

Wär schön, wenn mir jmd. helfen kann...sitz schon viel zu lang an dem Code dran... :(
 
G

Gast

Gast
Achso...die Klasse um die es sich dreht sollte ich vielleicht auch mitsenden...wenn jmd. die anderen Klassen dieses Projekts braucht kann er gerne nachfragen, aber da hat sich nicht wirklich was geändert...

Code:
import java.awt.Color;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;

/**Ein KreisZeichner erstellt einen Kreis mit dem Radius, der zwischen den 
 * beiden Punkten entsteht, an denen die Maus gedrückt und losgelassen wird.
 * Den Kreis wird in einem GrafikObjekt abgespeichert und das widerum in einem 
 * ArrayList-Objekt.
 * Der KreisZeichner erhält bei seiner Erzeugung ein ArrayList-Objekt und 
 * speichert es als seine Eigenschaft.
 */
public class KreisZeichner extends MouseAdapter
{
	int kreisZähler=0;
	private Point mittelpunkt=new Point();
	private Point startpunkt=new Point();
	Shape kreis;
	GrafikObjekt go=new GrafikObjekt(kreis);
	Shape alterKreis;
	Shape neuerKreis;
	ArrayList<GrafikObjekt> al;
	ZeichenPanel view;
	AffineTransform at;
	
	
	//Hier werden alle Kreise gespeichert:
	public KreisZeichner(ZeichenPanel view,ArrayList<GrafikObjekt> al)
	{
		this.al=al;
		this.view=view;
		
		//Das Lesezeichen für die Objekte (vergleichbar mit einem Index):
		//Iterator i=ll.iterator();
	}
	
	public void mousePressed(MouseEvent e) 
	{
		//Beim drücken einer Maustaste merkt sich der KreisZeichner die Position:
		mittelpunkt=e.getPoint();
	}

	public void mouseReleased(MouseEvent e) 
	{
		/*
		 * Ein Kreis soll nur durch drücken, genauer gesagt beim los lassen 
		 * der linken Maustaste aufgezogen werden und auch nur dann wird der 
		 * kreisZähler aktiv, daher muss festgestellt werden welche Maustaste 
		 * gedrückt wurde:
		 */
		e.getButton(); 
		
		/*Wird nur ausgeführt, wenn die linke Maustaste los gelassen wird!
		 */
		if (e.getButton()==1)
		{
			/*
			 * @param kreisZähler: Zählt die Anzahl der Linksklicks, also der 
			 * Kreise.
			 * TODO: Wenn kein Kreis AUFGEZOGEN, sondern nur links geklickt wird, 
			 * also ein Kreis mit dem Radius null "gezeichnet" wird (=kein Kreis) 
			 * zählt er diesen trotzdem als einen->nur hochzählen, wenn gedrückt 
			 * UND gezogen wird!(If...dragged...)
			 */
			kreisZähler++; 
			System.out.println(kreisZähler);
			
			/*
			 * Der Entfernung (Radius) r wird berechnet, zwischen Mittelpunkt 
			 * und dem Punkt an dem die linke Maustaste los gelassen wird:
			 */
			double r=e.getPoint().distance(mittelpunkt); 
			
			//X,- und Y-Koordinate für den Mittelpunkt des Kreises:
			startpunkt.x=mittelpunkt.x-(int)r;
			startpunkt.y=mittelpunkt.y-(int)r;
			
			/*Der Kreis, also ein Ellipse2D Objekt wird mit der Entfernung 
			 * (die in dieser Methode berechnet wird) als Parameter erschaffen:
			*/
			kreis=new Ellipse2D.Double(startpunkt.x, startpunkt.y, 2*r, 2*r);
			
			//Dieses wird dann in einem GrafikObjekt gespeichert:
			//Damit haben wir einen noch nicht transformierten Kreis geschaffen!
			GrafikObjekt go=new GrafikObjekt(kreis);
			
			//Hier wird dir Farbe der Kreise fest gelegt; HIER per Zufall bzw. Magentafarben:
			Color color=Color.magenta;
			//Color color=new Color((float)Math.random(),(float)Math.random(),(float)Math.random());
			go.color=color;
		
			//Der Kreis (GrafikObjekt) wird der ArrayList hinzugefügt:
			al.add(go);
			
			//Das ZeichenPanel wird "aktualisiert"(der Kreis gezeichnet):
			view.repaint();
		}
	}
	
	public void mouseClicked(MouseEvent e) 
	{
		/*TODO:Die AffineTransform, die auf den Kreis angewandt werden soll, 
		 *soll eine Eigenschaft des Grafikobjekts sein und mit einem Getter 
		 *geholt werden:
		 *Hier wird Sie in dieser Methode bestimmt... :(
		 */
		double dx=1200*Math.random()-600;
		double dy=800*Math.random()-400;
		at=AffineTransform.getTranslateInstance(dx, dy);//Nachricht wird an Transformation gesandt
		
		e.getButton();//Es soll herausgefunden werden welche Maustaste gedrückt wurde:
	
		/**Wenn mit der rechten Maustaste im JPanel geklickt wird soll
		 * herausgefunden werden wo, und ob ein Kreis dabei gewählt wurde
		 * und wenn ja, soll er transformiert werden:
		 */
		if (e.getButton()==3)
		{
			e.getPoint();
			for(GrafikObjekt go: al)
			{
				if(go.getShape().contains(e.getPoint()))
				{
					go=(GrafikObjekt)go.setShape(at.createTransformedShape((Shape) go));
					al.add(go);
					view.repaint();
				}
			}
		}
	}
}
 
G

Gast

Gast
Falls es jmd. hilft:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: GrafikObjekt
at KreisZeichner.mouseClicked(KreisZeichner.java:128)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
 
G

Gast

Gast
Ich glaubs nicht, IT WORKS..hier der veränderte Teil...falls es jmd. interessiert:

Code:
/**Wenn mit der rechten Maustaste im JPanel geklickt wird soll
		 * herausgefunden werden wo, und ob ein Kreis dabei gewählt wurde
		 * und wenn ja, soll er transformiert werden:
		 * TODO: Wenn 2 Kreise übereinander liegen werden beide verschoben!
		 */
		if (e.getButton()==3)
		{
			e.getPoint();
			for(GrafikObjekt go: al)
			{
				if(go.getShape().contains(e.getPoint()))
				{
					go.setShape(at.createTransformedShape(go.getShape()));
					
					//Die Farbe des transformierten Kreises:
					Color color=Color.magenta;
					go.color=color;
					
					//al.add(go);
					view.repaint();
}
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben