# Zeichenprogramm mit Factory-Pattern



## Sindbad1983 (6. Jun 2005)

Hi!

Dieses Mal wartet wieder viel Arbeit auf mich...und sehr schwer noch dazu find ich! 
Ich steh momentan noch bei einem vernünftigen konzeptuellen Entwurf, hab aber da schon das ein oder andere Problem:

Hier mal die Angabe meines Beispiels:

Vorweg: Am wichtigsten ist die Implementierung nach dem FABRIK-Pattern!!




> Einfaches Zeichenprogramm
> 
> Schreiben Sie ein Zeichenprogramm, mit dem einfache Figuren (Rechtecke, Ellipsen und Dreiecke)
> gezeichnet werden können.
> ...




Ich hab mir gedacht, ich könnt mal so herangehen:

1. eine abstrakte Klasse Figure mit einer abstrakten Methode paint()
2. 3 Unterklassen Rectangle, Circle, Eplise , die von Figure erben und die paint()-Methode verschieden implementieren
3. Ein Frame, das ein JPanel (die Zeichenfläche selbst) beeinhaltet ->also die GUI
4. eine abstrakte Klasse AbstractFigureFactory
5. 2 Klassen, die von dieser erben:  BlackAndWhiteFigureFactory    ColoredFigureFactory

denn es sollen figures entweder in Farbe oder in schw-weiß gezeichnet werden können!das sind meine 2 verschiedenen Fabrik-Ausprägungen...
Das soll man ja im Pull-Down-Menü auswählen können!
Je nach Auswahl werden dann die unterschiedlichen figures gezeichnet!


Kann ich das so machen?Hab ich das richtig verstanden?
Oder brauch ich da noch mehr Klassen?
Wer hilft mir bitte bei dem Beispiel?
  :bae:   :bae:   :bae:


----------



## Wildcard (6. Jun 2005)

Dein Ansatz ist soweit richtig. Wenn's Probleme gibt kannst du dich ja melden  :wink:


----------



## Sky (6. Jun 2005)

Ich weiß nicht, ob dies dann an der Aufgabenstellung vorbei geht, aber hier noch ein paar Tips:

- circle ist eine spezielle ellipse; könnte man also auch deshalb so ableiten (oder meintest Du eher 'triangle', weils Dreieck noch fehlt...)
- BlackAndWhiteFigureFactory könnte eine spezielle ColoredFigureFactory sein (hier sind dann einfach schon die Farben gesetzt) ODER ColoredFigureFactory könnte BlackAndWhiteFigureFactory erweitern (um die Eigenschaft farben darzustellen)


----------



## Roar (6. Jun 2005)

ich nehme an du kennst das: http://n.ethz.ch/student/besigg/forum/tutorial/Tutorial.zip :?:


----------



## Sindbad1983 (6. Jun 2005)

ja stimmt, ich mach statt ellipse ein dreieck

nein, wir müssen BlackAndWhiteFigureFactory und ColordFigureFactory getrennt implementieren...

ich werd jetzt gleich mal anfangen...


----------



## Sindbad1983 (6. Jun 2005)

zusätzlich brauch ich ja noch ein GUI-Element, in dem ich das ganze ja anzeige:

ich hab mir das so gedacht:

ich mach eine eigene Klasse MyPanel, die von JPanel erbt, und die dann meine Zeichenfläche darstellen soll!

Ein meiner Klasse PaintFrame extends Frame erzeug ich dann
MyPanel und füg es dem Frame hinzu!

Ich brauch die 2 unterschiedlichen Klassen, weil bei JFrame muss ich die Menüzeile hinzufügen und bei MyPanel muss ich die Mausereignisse handeln...
sind diese Gedanken richtig?

Oder soll ich das anderes/besser machen?


----------



## Wildcard (6. Jun 2005)

Grundsätzlich richtig, würde aber statt eines JPanels eine JComponent nehmen, da du ja nur zeichnen willst, und JComponent die Basis Klasse ist...


----------



## Sindbad1983 (6. Jun 2005)

:roll: 

was sagt ihr zu meinem Einstieg?
Kann ich mit dem so weitertun?
Oder soll ich da schon was ändern?

Bitte um Kritik:



```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;


public class PaintFrame extends JFrame implements ActionListener{
	
	
	Zeichenflaeche zeichenflaeche;
	

	
	public PaintFrame(String titel){
		super(titel);
		
		
		
		
		
		Container c=getContentPane();
		
		zeichenflaeche=new Zeichenflaeche();
	
		c.add(zeichenflaeche);
		
	
		
	}
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 m.add(new MenuItem("Rot"));
		 m.add(new MenuItem("Blau"));
		 m.add(new MenuItem("Grün"));
		 bar.add(m);
		 setMenuBar(bar);
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		frame.setSize(600,600);
		frame.setLocation(300,300);
		frame.setVisible(true);
		frame.makeMenu();
	
		
		
	}

	

}
```



```
public class Zeichenflaeche extends JPanel implements MouseListener, MouseMotionListener, ActionListener{
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	
	public Zeichenflaeche(){
		setBackground(Color.RED);
		this.addMouseListener(this);
	}
	

	public void mouseClicked(MouseEvent e) {
		
		
	}

	public void mousePressed(MouseEvent e) {
		
		pressedX=getX();
		pressedY=getY();
		
		
		
		
	}

	public void mouseReleased(MouseEvent e) {
		
		releasedX=getX();
		releasedY=getY();
		repaint();
	
	
		
	}

	public void mouseEntered(MouseEvent e) {
		
		
	}

	public void mouseExited(MouseEvent e) {
		
		
	}

	public void mouseDragged(MouseEvent e) {
	
		
	}

	public void mouseMoved(MouseEvent e) {
		
		
	}

	public void actionPerformed(ActionEvent e) {
		
		
	}
	
}
```


```
public abstract class AbstractFigureFactory {
	
	public abstract Figure createFigure();

}
```


```
public class BlackAndWhiteFigureFactory extends AbstractFigureFactory{

	
	public Figure createFigure() {
		
		
		//return new ?????
		
		
		
		return null;//das stimmt natürlich nicht! 
	}
	


}
```


und dasselbe bei ColoredFigureFactory..da kenn ich mich jetzt überhaupt nicht mehr aus!
Ich mein, wenn ich es ohne das Fabrik-Pattern implementieren müsste, würd ich glaub ichs schaffen..
aber das verwirrt mich irgendwie..

Was wären die nächsten Schritte?
Danke!!!


----------



## Sindbad1983 (7. Jun 2005)

kann mir da jemand helfen?
ich steh momentan ein bissl an


----------



## Sky (7. Jun 2005)

Hier ist's ganz gut beschrieben: http://www.java-forum.org/de/javabuch/html/k100068.html#ixa100630


----------



## Sindbad1983 (7. Jun 2005)

in dem Beispiel (Handbuch der Programmierung) kommt vor:




```
001 /* Listing1014.java */
002 
003 //------------------------------------------------------------------
004 //Abstrakte Produkte
005 //------------------------------------------------------------------
006 abstract class Product1
007 {
008 }
009 
010 abstract class Product2
011 {
012 }
013 
014 //------------------------------------------------------------------
015 //Abstrakte Factory
016 //------------------------------------------------------------------
017 abstract class ProductFactory
018 {
019   public abstract Product1 createProduct1();
020 
021   public abstract Product2 createProduct2();
```


bei mir gibts eigentlich nur ein Produkt, oder?


denn Rectangle, Circle und Triangle sind alle eine Figure!
Oder????

Also würd bei mir passen:





```
public abstract class AbstractFigureFactory{

public abstract Figure createFigure();

}
```


für mich logischer wäre aber:


```
public abstract class AbstractFigureFactory {
	
	public abstract Figure createRectangle();
	public abstract Figure createCircle();
	public abstract Figure createTriangle();

}
```

Mann, das ist echt verwirrend! :bloed:


----------



## Sky (7. Jun 2005)

Wenn Du nur eine Methode 
	
	
	
	





```
public abstract Figure createFigure();
```
 hast, so brauchst Du doch ein Unterscheidungskriterium, wann welche Figur erzeugt werden soll, d.h. Du brauchst noch einen Parameter:

z.B. 
	
	
	
	





```
public abstract Figure createFigure(int type);
```
oder 
	
	
	
	





```
public abstract Figure createFigure(String type);
```


----------



## Sindbad1983 (7. Jun 2005)

was ist, wenn ich es so mache??

geht das auch??



```
public abstract class AbstractFigureFactory {
	
	public abstract Figure createRectangle();
	public abstract Figure createCircle();
	public abstract Figure createTriangle();
	
}
```



```
public class BlackAndWhiteFigureFactory extends AbstractFigureFactory{

	
	public Figure createRectangle() {
		
		return new Rectangle();
	}

	
	public Figure createCircle() {
		
		return new Circle();
	}

	
	public Figure createTriangle() {
	
		return new Triangle();
	}
	
	
	
}
```

müsste auch funktionieren, oder?


----------



## Beni (7. Jun 2005)

Normalerweise macht man mehrere Factories: eine für Rechtecke, eine für Kreise... Die sammelt man dann irgendwo in einer Liste, und lässt den Benutzer eine Factory wählen. Das hat den Vorteil, dass man ganz leicht neue Figuren (und ihre Factories) hinzufügen kann, ohne irgendwo seltsame Konstanten zu ändern.


----------



## Sindbad1983 (7. Jun 2005)

ja...ich weiß, so wärs auch nicht soooo schwer, aber wir müssen es so machen:

mit einer Klasse BlackAndWhiteFactory, die nur farblose figures zeichnet
und eine Klasse ColoredFactory, die färbige figures zeichnet!
Und die Farbe soll man über die Menüleiste einstellen können!


Das bringt mich komplett durcheinander!  :cry:   :cry:   :cry: 

Ich kann mir das grad überhaupt nicht vorstellen!  :autsch:


----------



## Sindbad1983 (7. Jun 2005)

ich lass jetzt das mit den Farben weg, und vereinfach das somit erstmal ein bisschen!

Ich machs jetzt so, wies Beni mir empfohlen hat!


Ich hab eine AbstractFactory und 3 Unterklassen: RectangleFactory, CircleFact......


----------



## Sky (7. Jun 2005)

Beni hat gesagt.:
			
		

> Normalerweise macht man mehrere Factories: eine für Rechtecke, eine für Kreise... Die sammelt man dann irgendwo in einer Liste, und lässt den Benutzer eine Factory wählen. Das hat den Vorteil, dass man ganz leicht neue Figuren (und ihre Factories) hinzufügen kann, ohne irgendwo seltsame Konstanten zu ändern.



Nun erschließt sich mir nicht mehr ganz der Mehrwert einer Factory, wenn ich genau eine Factory für eine Figure habe... dann kann ich mir auch ein Interface Figure erstellen und drei Klassen für Kreis, Dreieck und Rechteck, welche das Interface implementieren.
Meines Erachtens sollte es für diese Problemstellung eine Factory geben, welche entweder über einen Parameter oder mittels verschiedener Methoden (createCircle, createRectangle... ) die Frigure liefern.


----------



## Sindbad1983 (7. Jun 2005)

naja, ich habs jetzt so probiert: geht aber leider nicht!

er wirft mir ne NullPointerException:


ich such schon wieder seit 2 Stunden den fehler, komm aber nicht drauf

ich versteh das nicht: da programmier ich letzte Woche einen Email-Client und dann hab ich diese Woche massive Probleme mit dynamischer Bindung!  :cry:   :cry: 

Vielleicht kann mir jemand einen Tipp  :bae:  geben!

Hier nur ein Auszug der wichtigsten Klassen:




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


public abstract class Figure extends JComponent {
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public void getpressedXY(int x, int y){
		pressedX=x;
		pressedY=y;
	}
	
	public void getreleasedXY(int x, int y){
		releasedX=x;
		releasedY=y;
	}

	public abstract void paint(Graphics g);

}
```


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


public class Rectangle extends Figure{
	

	
	public void paint(Graphics g) {
		g.setColor(Color.blue);
		g.fillRect(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
	}
}
```

Klasse Circle und Triangle genauso nur mit anderer paint-Methode!



```
public class PaintFrame extends JFrame implements ActionListener{
	
	
	Zeichenflaeche zeichenflaeche;
	AbstractFigureFactory factory;
	
	public PaintFrame(String titel){
		super(titel);
		
		Container c=getContentPane();
		zeichenflaeche=new Zeichenflaeche(factory);
		c.add(zeichenflaeche);
	}
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 m.add(new MenuItem("Rot"));
		 m.add(new MenuItem("Blau"));
		 m.add(new MenuItem("Grün"));
		 bar.add(m);
		 setMenuBar(bar);
	}
	
	public void actionPerformed(ActionEvent e) {
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		frame.setSize(600,600);
		frame.setLocation(300,300);
		frame.setVisible(true);
		frame.makeMenu();
			
	}

}
```


```
public class Zeichenflaeche extends JPanel implements MouseListener, MouseMotionListener,  KeyListener{
	
	AbstractFigureFactory factory;
	Figure figure;
	Graphics g;
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	
	public Zeichenflaeche(AbstractFigureFactory factory){
		factory=factory;
		setBackground(Color.RED);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.addKeyListener(this);
	}
	
	public Figure makeFigure(){
		Figure figure=factory.createFigure();
		
		figure.paint(g);
		return figure;
	}
	

	public void mouseClicked(MouseEvent e) {	
	}

	public void mousePressed(MouseEvent e) {
		
		pressedX=getX();
		pressedY=getY();
		figure.getpressedXY(pressedX,pressedY);
		
	}

	public void mouseReleased(MouseEvent e) {
		
		releasedX=getX();
		releasedY=getY();
		figure.getreleasedXY(releasedX,releasedY);
		repaint();

	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
	}

	

	public void keyTyped(KeyEvent e) {
		 char key = e.getKeyChar();
			
			if(key==KeyEvent.VK_ENTER){
				factory=new RectangleFactory();
			}
			else if(key==KeyEvent.VK_SPACE){
				factory=new CircleFactory();
			}else{
				factory=new TriangleFactory();
			
			}
		
	}

	public void keyPressed(KeyEvent e) {
	}
		
	public void keyReleased(KeyEvent e) {	
	}
	
}
```


```
public abstract class AbstractFigureFactory {
	
	public abstract Figure createFigure();
	
}
```


```
public class RectangleFactory extends AbstractFigureFactory{

	
	public Figure createFigure() {
		
		return new Rectangle();
	}
}
```

die anderen beiden genauso!


----------



## Wildcard (7. Jun 2005)

```
factory=factory;
```
das bringt nichts! muss heißen:

```
this.factory=factory;
```


----------



## Sindbad1983 (7. Jun 2005)

ich hab diese Methode noch verändert:


```
public void keyTyped(KeyEvent e) {
		 char key = e.getKeyChar();
			
			if(key==KeyEvent.VK_ENTER){
				factory=new RectangleFactory();
				Zeichenflaeche flaeche=new Zeichenflaeche(factory);
				Figure figure=flaeche.makeFigure();
			}
			else if(key==KeyEvent.VK_SPACE){
				factory=new CircleFactory();
				Zeichenflaeche flaeche=new Zeichenflaeche(factory);
				Figure figure=flaeche.makeFigure();
			}else{
				factory=new TriangleFactory();
				Zeichenflaeche flaeche=new Zeichenflaeche(factory);
				Figure figure=flaeche.makeFigure();
			
			}
		
	}
```


naja...geht aber auch nicht!

Sobald ich auf die Fläche klicke, kommen viiiiiiiele Exceptions !   :cry: 

Mann..sowas ist echt frustrierend!


----------



## Wildcard (7. Jun 2005)

hast du das geändert? Wo kommen die Exceptions genau? Dann muss ich nicht so viel suchen  :wink:


----------



## Sindbad1983 (7. Jun 2005)

ja das hab ich schon eingefügt!

Sobald ich auf die Zeichenfläche klicke, kommt im Ausgabefenster folgendes:


Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at figures.Zeichenflaeche.mousePressed(Zeichenflaeche.java:52)
	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)


Danke, dass du mir hilfst!

das ganze sagt mir eher wenig! 

Ich weiß nämlich schon wieder nicht mehr weiter bzw. was ich noch ändern könnte!  :###

wie lange programmíerst du schon?


----------



## stev.glasow (7. Jun 2005)

Sindbad1983 hat gesagt.:
			
		

> ```
> public void keyTyped(KeyEvent e) {
> char key = e.getKeyChar();
> 
> ...



Was soll das eigentlich bringen, bis auf 'factory' sind alle Varablen lokal.


----------



## mic_checker (7. Jun 2005)

Wird denn die Methode makeFigure() auf jeden Fall aufgerufen bevor du auf das figure Objekt zugreifst?


----------



## Beni (7. Jun 2005)

sky80 hat gesagt.:
			
		

> Beni hat gesagt.:
> 
> 
> 
> ...


Und wie erstellst du dann einen neuen Kreis, wenn du keine Factory hast :bahnhof: ? Mit einem fest einkodierten "new Circle" hast du verloren, weil alles dynamische weg ist.


----------



## Wildcard (7. Jun 2005)

figure ist null.
Wie stevg schon geschrieben hat erstellst du immer lokale Variablen anstatt auf die Instanz-Variablen zuzugreifen.
also statt

```
Figure figure=factory.createFigure();
```


```
figure=factory.createFigure();
```
aber wieso hat Zeichenfläche überhaupt eine Instanzvariable figure? Das heißt ja das es auf der Zeichenfläche nur eine Figure gibt?  :bahnhof:


----------



## Sindbad1983 (7. Jun 2005)

wenn z.B. die Enter-Taste gedrückt wird, dann ein RectangleFactory-Object erzeugt werden->dieses übergib ich dann der Zeichenfläche und ruf mit dieser die makeFigure()-Methode auf..diese gibt eine Figur zurück

so sollte es zumindest sein...oder auch nicht...das ist ja mein Problem, dass ich selber nicht weiß, wie das genau geht..  :cry: 

habs nur mal so probiert


----------



## stev.glasow (7. Jun 2005)

Weißt du was der Unterschied zwischen lokalen Variablen und Instanz-Variablen ist?


----------



## Wildcard (7. Jun 2005)

Sindbad1983 hat gesagt.:
			
		

> wenn z.B. die Enter-Taste gedrückt wird, dann ein RectangleFactory-Object erzeugt werden


das heißt du erzeugst wenn du eine Figure erstellen willst eine neue Factory???
Deine Factorys sollte es eigentlich nur einmal geben. Die Factory an die Zeichenfläche zu übergeben ist auch ziemlich seltsam.
Die Zeichenfläche sollte nur die figure bekommen die die Factory erzeugt hat, und nicht die Factory selbst...


----------



## Sindbad1983 (7. Jun 2005)

naja..

Instanzvariablen sind Variablen, die man in der Klasse deklariert ->diese sind dann die "Daten" der  erzeugten Objekte  ->und mit Hilfe von Methoden kann man die Werte der Variablen verändern bzw. hat Zugriff darauf!

Lokale Variablen sind nur in einem Block sichtbar..naja aber mehr weiß ich da schon nicht mehr drüber!
Man kann auf Lokale Variablen nicht zugreifen, weil sie ja nicht sichtbar sind von außen!
Außer mit Hilfe von Methoden!

Auf Instanzvariablen hingegen ist Zugriff möglich, außer sie sind private!
Stimmt das so?


----------



## stev.glasow (7. Jun 2005)

jor stimmt soweit, außer das mit dem private, aber ist hier für egal.

Aber ich verstehe dann nicht warum du diese lokal machst:
Zeichenflaeche flaeche=new Zeichenflaeche(factory);
Figure figure=flaeche.makeFigure(); 
diese existieren so doch nur n dem Block.


----------



## Sindbad1983 (7. Jun 2005)

naja hast eigentlich Recht!




```
public Zeichenflaeche(){
		
		setBackground(Color.RED);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.addKeyListener(this);
	}
	
	public Figure makeFigure(){
		Figure figure=factory.createFigure(); //eventuell Figure weg!
		
		figure.paint(g);
		return figure;
	}

                    .
                    .
                    .
  

	public void keyTyped(KeyEvent e) {
		 char key = e.getKeyChar();
			
			if(key==KeyEvent.VK_ENTER){
				factory=new RectangleFactory();
				Zeichenflaeche flaeche=new Zeichenflaeche();
				figure=flaeche.makeFigure();
			}
			else if(key==KeyEvent.VK_SPACE){
				factory=new CircleFactory();
				Zeichenflaeche flaeche=new Zeichenflaeche();
				figure=flaeche.makeFigure();
			}else{
				factory=new TriangleFactory();
				Zeichenflaeche flaeche=new Zeichenflaeche();
				figure=flaeche.makeFigure();
			
			}
		
	}
```

aber so stimmts ja auch nicht, oder?

außerdem:

ich muss zu Beginn der Klasse Figure figure deklarieren, weil ich sonst ja bei 


```
public void mousePressed(MouseEvent e) {
		
		pressedX=getX();
		pressedY=getY();
		figure.getpressedXY(pressedX,pressedY);
		
	}
```

keinen Zugriff mehr hätte oder?


----------



## Sindbad1983 (7. Jun 2005)

boa, jetzt verzweifle ich gleich:

Zeichenflaeche flaeche=new Zeichenflaeche() ist ja auch falsch!
Das darf ich auch nicht lokal machen

mir fehlt da jetzt absolut der Durchblick!  :cry:   :cry:   :cry:


----------



## Sindbad1983 (8. Jun 2005)

also nochmal zur Verständnis:


wenn ich 

Figure figure;

als Instanzvariable deklarier, dann heißt das, dass ich eine Figure-Variable hab mit den Instanzvariablen von Figure(also pressedX, pressedY etc)
D.h. ich kann maximal eine Figur in Zeichenflaeche speichern?
->das würd ich eigentlich nicht wollen!
Stimmt das so?


----------



## Beni (8. Jun 2005)

Wenn du eine Instanzvariable hast, bedeutet dies, dass pro Zeichenfläche nur eine Figure existiert (bzw, angezeigt wird).

Das ist ein bisschen unglücklich, deshalb würde ich diese Figuren in einer Liste sammeln.


```
List figures = new ArrayList();
figures.add( ... );
```

Siehe hier.


----------



## Sindbad1983 (8. Jun 2005)

ja ist vielleicht ne gute Idee..
ich werds morgen mit einer Liste probiern!

aber ich sag mal, das wird nicht das zentrale Problem sein!

Denn es kann ja bis dato nicht mal 1 Figur gezeichnet werden!
Und das Problem kann nur in der Klasse Zeichenflaeche liegen, denk ich mir mal!

Naja..vielleicht kann mir ja trotzdem noch jemand einen Hinweis in Richtung Lösung geben! 
Gute Nacht!

Danke für eure Hilfe!
ciao, bis morgen


----------



## Sky (8. Jun 2005)

Beni hat gesagt.:
			
		

> sky80 hat gesagt.:
> 
> 
> 
> ...



Also, ich habe mir die FAQ noch einmal durchgelesen, und dort steht zum Factory-Pattern folgendes Beispiel:

```
public class Foo {
  Foo() { //Konstruktor nur für package zugänglich, da factory Methode in andere Klasse im selben Package liegt
  }
}

public class Bar {
  Bar() { //Konstruktor nur für package zugänglich, da factory Methode in andere Klasse im selben Package liegt
  }
}

public class FooBarFactory {
  public static Foo getFoo( Settings s ) { //Factory - Methode für Foo
    Foo f = new Foo(); //erlaubt
    //intialisiere f
    return f;
  }

  public static Bar getBar( Settings s ) { //Factory - Methode für Bar
    Bar b = new Bar(); //erlaubt
    //intialisiere b
    return b;
  }
}
```

Wenn ich dies nun auf das Sindbad's Problem beziehe, so würde meine Interpretation so aussehen:

```
class Rectangle extends Figure {
  Rectangle() { //Konstruktor nur für package zugänglich, da factory Methode in andere Klasse im selben Package liegt
  }
  // getter und setter
}

class Circle extends Figure {
  Circle() { //Konstruktor nur für package zugänglich, da factory Methode in andere Klasse im selben Package liegt
  }
  // getter und setter
}

class FigureFactory {
  // Rückgabewert könnte natürlich auch Rectangle sein
  public static Figure getRectangle( Settings s ) { //Factory - Methode für Foo
    Rectangle r = new Rectangle(); //erlaubt
    //intialisiere r
    return r;
  }

  // Rückgabewert könnte natürlich auch Circle sein
  public static Figure getCircle( Settings s ) { //Factory - Methode für Bar
    Circle c = new Circle(); //erlaubt
    //intialisiere c
    return c;
  }
}
```


----------



## Sindbad1983 (8. Jun 2005)

naja...aber das hab ich eh im Grund auch oder?

ich hab halt nur statt einer FigureFactory eine abstrake Klasse mit 3 Unterklassen...

also ich glaub von der Konzeption müsste es schon stimmen


----------



## Sindbad1983 (8. Jun 2005)

So, ich hab jetzt die beiden Klassen PaintFrame und Zeichenflaeche nochmals verändert, und ich glaube ich bin jetzt noch näher an einer möglichen Lösung!

Es wirft mir zumindest keine Exception mehr!

außerdem übergib ich nicht mehr der Zeichenflaeche die AbstractFigureFactory, sondern nur mehr der makeFigure-Methode!

Ich möcht jetzt einfach nur mal, dass er 1 Figur (z.B. ein Rechteck zeichnet)..das wär ein Traum!

Leider zeichnet er aber nichts!


Ich bin jetzt echt am Ende mit meinem Latein!  :cry: 

Ich wüsst auch nicht mehr, wo ich noch nachschaun könnt, bzw. was ich ändern könnte!  :roll: 



```
public class PaintFrame extends JFrame implements ActionListener{
	
	
	
	
	public PaintFrame(String titel){
		super(titel);
		
		Container c=getContentPane();
		Zeichenflaeche zeichenflaeche=new Zeichenflaeche();
		c.add(zeichenflaeche);
	}
	
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 m.add(new MenuItem("Rot"));
		 m.add(new MenuItem("Blau"));
		 m.add(new MenuItem("Grün"));
		 bar.add(m);
		 setMenuBar(bar);
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		frame.setSize(600,600);
		frame.setLocation(300,300);
		frame.setVisible(true);
		frame.makeMenu();
			
	}

}
```



```
public class Zeichenflaeche extends JPanel implements MouseListener, MouseMotionListener,  KeyListener{
	
	Figure figure;
	Graphics g;
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	
	public Zeichenflaeche(){
	
		
		setBackground(Color.RED);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.addKeyListener(this);
		
		//ArrayList list=new ArrayList(); für mehrere Figuren...jetzt soll erstmal 1 Figure gezeichnet werden
	}
	
	public Figure makeFigure(AbstractFigureFactory factory){
		Figure figure=factory.createFigure(); 
		
		figure.paint(g);
		return figure;
	}
	

	public void mouseClicked(MouseEvent e) {
		
		
	}

	public void mousePressed(MouseEvent e) {
		
		pressedX=getX();
		pressedY=getY();
		figure.getpressedXY(pressedX,pressedY);
		
	}

	public void mouseReleased(MouseEvent e) {
		
		releasedX=getX();
		releasedY=getY();
		figure.getreleasedXY(releasedX,releasedY);
		repaint();

	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
	}

	

	public void keyTyped(KeyEvent e) {
		 char key = e.getKeyChar();
		 
		 AbstractFigureFactory factory;
			
			if(key==KeyEvent.VK_ENTER){
				factory=new RectangleFactory();
				
			}
			else if(key==KeyEvent.VK_SPACE){
				factory=new CircleFactory();
				
				
			}else{
				factory=new TriangleFactory();
				
			
			}
			
			Zeichenflaeche flaeche=new Zeichenflaeche();
			
			Figure figure=flaeche.makeFigure(factory);
		
		
	}

	public void keyPressed(KeyEvent e) {
	}
		
	public void keyReleased(KeyEvent e) {	
	}
	
}
```


DANKE!


----------



## Sindbad1983 (8. Jun 2005)

maa,ich hoffe echt, dass mir da heut noch wer hilft...
sonst seh ich schwarz..
das Beispiel beinhaltet nämlich sehr viel Wichtiges! ;-(


----------



## Wildcard (8. Jun 2005)

:autsch: 
Diese beiden sind immer null. Was machst du damit?

```
Figure figure;
   Graphics g;
```

Falls ich du dich jetzt doch entschlossen hast aus den Figures JComponents zu machen, dann muss dir auch klar sein das du
sie wie ganz normale Komponenten auf ein Panel adden musst um sie sehen zu können.
Ich rate dir weiterhin dazu nicht von JComponent zu erben und ein Graphics-Objekt durchzureichen...

```
if(key==KeyEvent.VK_ENTER){
            factory=new RectangleFactory();
            
         }
         else if(key==KeyEvent.VK_SPACE){
            factory=new CircleFactory();
            
            
         }else{
            factory=new TriangleFactory();
```
Factorys werden nicht mal eben auf Knopfdruck erstellt. Sie existieren nur 1mal!
An dieser Stelle solltest du sie schon gar nicht instanzieren, weil deine Zeichenfläche absolut gar nichts mit der Factory zu tun hat.
Eine Zeichenfläche kriegt Figuren die sie darstellen soll und hat weder mit deren Instanzierung zu tun, noch 'kennt' sie die Factory.
Setz dich mal in Ruhe hin, mach ein vernünftiges Klassendesign, mach dir Gedanken wie du das Zeichnen realisieren willst etc.


----------



## Sindbad1983 (8. Jun 2005)

ja da wirst Recht haben...ich glaub, dass da doch noch einiges falsch ist!
Mir dürfte das mit den Refernzen doch irgendwie noch immer nicht restlos klar sein..  :cry: 


Ich hab jetzt mal das Beispiel total vereinfacht, nur mit einer Klasse Rechteck, dem Frame und dem Panel!


Damit ich das mal im ganz Kleinen durchspielen kann und alles versteh, was da so passiert! 

Er wirft zwar keine Exceptions, aber zeichnen tut er auch nichts!

Ich versteh das einfach nicht!   
Ich find da nie den Fehler!



```
public class Rectangle extends JComponent{
	
	
	

	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public void getpressedXY(int x, int y){
		pressedX=x;
		pressedY=y;
	}
	
	public void getreleasedXY(int x, int y){
		releasedX=x;
		releasedY=y;
	}
	


	public void paint(Graphics g) {
		g.setColor(Color.blue);
		g.fillRect(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);

	}
     

}
```


```
public class PaintFrame extends JFrame implements ActionListener{
	
	
	
	
	public PaintFrame(String titel){
		super(titel);
		
		Container c=getContentPane();
		Zeichenflaeche zeichenflaeche=new Zeichenflaeche();
		c.add(zeichenflaeche);
		System.out.println("bbbb");
	}
	
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 m.add(new MenuItem("Rot"));
		 m.add(new MenuItem("Blau"));
		 m.add(new MenuItem("Grün"));
		 bar.add(m);
		 setMenuBar(bar);
		 System.out.println("ccc");
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		frame.setSize(600,600);
		frame.setLocation(300,300);
		frame.setVisible(true);
		frame.makeMenu();
			
	}

}
```


```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.*;


public class Zeichenflaeche extends JPanel implements MouseListener, MouseMotionListener{
	
	
	Graphics g=getGraphics();
	
	Rectangle r;
	
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	
	
	
	
	public Zeichenflaeche(){
		
		System.out.println("eee");
	
		
		setBackground(Color.RED);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		
		
		System.out.println("ddd");
		
	
	}
	
	
	

	public void mouseClicked(MouseEvent e) {
		
		
	}

	public void mousePressed(MouseEvent e) {
		
		r=new Rectangle(); //das weiß ich nicht, ob stimmt...ich muss ja aber ein Rechteck irgendwo erzeugen, sonst bekomm ich ne NullPointerException
		
		System.out.println("aaaaa");
		this.pressedX=getX();
		this.pressedY=getY();
	
		r.getpressedXY(pressedX,pressedY);
		System.out.println("zzzz");
	
		
		
	}

	public void mouseReleased(MouseEvent e) {
		
		System.out.println("yyyyy");
		this.releasedX=getX();
		this.releasedY=getY();
		r.getreleasedXY(releasedX,releasedY);
		repaint();
		
		System.out.println("ffff");

	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
	}

	
	
}
```


ich hab oben eine Instanzvariable Rectangle r;

wenn ich dann sag:


```
r.getpressedXY(pressedX,pressedY);
```

dann müsste er eigentlich den x und y -Wert im Rechteck setzen oder?


----------



## Wildcard (8. Jun 2005)

1) deine Methoden sind falsch benannt. 'get' bedeutet IMMER das du etwas zurückbekommst (auch auf die Kamelschreibweise achten) alles andere wird völlig verwirrend!
2) anstatt mit getX, getY zu arbeiten gehts viel einfach wenn du gleich getClickPoint verwendest.
3) Nenn deine Klasse nicht Rectangle weils diese Klasse schon gibt!
3)Wie gesagt, wenn du Rectangle von JComponent ableitest dann musst du diese Komponente eben genau wie ein JLabel deinem Panel hinzufügen, sonst wirst du da nie was sehen...


----------



## Sindbad1983 (8. Jun 2005)

ja aber wie hinzufügen?

normalerweise sag ich:


```
JPanel p=new JPanel();

JButton b=new JButton("B");

p.add(b);
```


aber das geht da nicht so einfach...
ich hätts im Konstruktor versucht, aber das funktioniert auch nicht...


```
add(r);
```


----------



## Wildcard (8. Jun 2005)

doch genau so:

```
add(r);
```
vorher allerdings die Bounds setzen da du sonst wenig sehen wirst.


----------



## Sindbad1983 (8. Jun 2005)

Leider....geht nicht!
Ich verstehs nicht!
Ich müsst doch jetzt eigentlich an alles gedacht haben..





```
public class Zeichenflaeche extends JPanel implements MouseListener, MouseMotionListener{
	
	
	Graphics g=getGraphics();
	
	
	Rectangle r;
	
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public Zeichenflaeche(){
		
		System.out.println("eee");
		setBounds(0,0,600,600);
	
		
		setBackground(Color.RED);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		System.out.println("ddd");
	}
	
	
	

	public void mouseClicked(MouseEvent e) {
		
		
	}

	public void mousePressed(MouseEvent e) {
		
		r=new Rectangle();
		add(r);
		
		
		System.out.println("aaaaa");
		this.pressedX=getX();
		this.pressedY=getY();
	
		r.getpressedXY(pressedX,pressedY);
		System.out.println("zzzz");
	
		
		
	}

	public void mouseReleased(MouseEvent e) {
		
		System.out.println("yyyyy");
		this.releasedX=getX();
		this.releasedY=getY();
		r.getreleasedXY(releasedX,releasedY);
		repaint();
		
		System.out.println("ffff");

	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
	}

	
	
}
```


----------



## Wildcard (8. Jun 2005)

Nein! setBounds auch auf r aufrufen!
Denk auch dran das jede JComponent ihr eigenes Koordinatensystem hat, und du deshalb bei 0,0 anfangen musst zu zeichnen!


----------



## Sindbad1983 (8. Jun 2005)

tut mir leid...es geht nicht!

 es muß für jede Komponente die genaue Position definiert werden, sowie die Breite und die Höhe!Die werden für jede Komponente über die Methode setBounds() festgelegt.

aber das Rechteck  verändert ja immer seine Position...

ich hab so gemacht:




```
r.setBounds(pressedX,pressedY,releasedX,releasedY);
```

und eben noch bei der Zeichenfläche:


```
setBounds(0,0,600,600);
```


----------



## Wildcard (8. Jun 2005)

```
setBound(int x, int y, int width, int heigth);
```


```
r.setBounds(pressedX,pressedY,releasedX,releasedY);
```
nicht ganz das selbe  :wink: 



			
				Wildcard hat gesagt.:
			
		

> Denk auch dran das jede JComponent ihr eigenes Koordinatensystem hat, und du deshalb bei 0,0 anfangen musst zu zeichnen!


hast du das auch schon geändert?


----------



## Sindbad1983 (8. Jun 2005)

du meinst wohl setBounds(int x, int y...etc) oder?

weil bei setBound gibts nur setBound(true) !?!

und:



> Denk auch dran das jede JComponent ihr eigenes Koordinatensystem hat,



das versteh ich nicht


hab eh setBounds(0,0,....) gemacht!

Oder ist das was anderes?


----------



## Wildcard (8. Jun 2005)

Sindbad1983 hat gesagt.:
			
		

> du meinst wohl setBounds(int x, int y...etc) oder?
> 
> weil bei setBound gibts nur setBound(true) !?!


typo...


----------



## Sindbad1983 (8. Jun 2005)

typo?


----------



## Wildcard (8. Jun 2005)

Typo   :bae:


----------



## Sindbad1983 (8. Jun 2005)

> durch Hast und Unachtsamkeit.


..geil

 :shock: 

danke, wieder was Neues gelernt!  :idea: 



vielleicht so:


```
r.setBounds(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
```

das hingegen ist mir noch nicht ganz klar



> Denk auch dran das jede JComponent ihr eigenes Koordinatensystem hat,



genügt da nicht 


```
setBounds(0,0,600,600);
```


??


----------



## Wildcard (8. Jun 2005)

Derzeit zeichnest du so:


```
g.fillRect(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
```
Da dein Rectangle aber eine eine JComponent ist hat sie ein eigenes Koordinatensystem das eben auch wieder bei 0,0 anfängt.
pressed/released bezieht sich aber auf das Koordinaten-System des Panels, da dort der MouseClick registriert wurde.
Dieser Code zeichnet also auserhalb der Komponete bzw gar nicht  :wink:

EDIT:

```
r.setBounds(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
```
nimm Math.abs, sonst kriegst du Probleme wenn der user das Rechteck nach oben aufzieht


----------



## Sindbad1983 (8. Jun 2005)

mensch, ich bin jetzt tief verzweifelt...

mir kommt jetzt alles durcheinander...swing, awt...was weiß ich..

ich hab jetzt noch was anderes probiert... ohne JComponent..aber das funktioniert auch nicht!

Jetzt brech ich gleich!

Wird wieder mal Zeit für ein Erfolgserlebnis!
Hab schon 2 Tage lang keine mehr gehabt!  :cry:   :cry:   :cry: 



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


public class Rectangle{
	
	
	

	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public void getpressedXY(int x, int y){
		pressedX=x;
		pressedY=y;
	}
	
	public void getreleasedXY(int x, int y){
		releasedX=x;
		releasedY=y;
	}
	


	public void paintComponent(final java.awt.Graphics g1 )   { 
		final java.awt.Graphics2D g =( java.awt.Graphics2D )g1; 
		g.setColor(Color.black);
		g.fillRect(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);

	}


}
```


```
public class PaintFrame extends JFrame implements ActionListener{
	
	
	
	
	public PaintFrame(String titel){
		super(titel);
		
		Container c=getContentPane();
		Zeichenflaeche zeichenflaeche=new Zeichenflaeche();
		c.add(zeichenflaeche);
		System.out.println("bbbb");
	}
	
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 m.add(new MenuItem("Rot"));
		 m.add(new MenuItem("Blau"));
		 m.add(new MenuItem("Grün"));
		 bar.add(m);
		 setMenuBar(bar);
		 System.out.println("ccc");
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		
		frame.setSize(600,600);
		frame.setLocation(300,300);
		frame.setVisible(true);
		frame.makeMenu();
			
	}

}
```


```
public class Zeichenflaeche extends JPanel implements MouseListener, MouseMotionListener{
	
	
	
	Rectangle r;
	
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public Zeichenflaeche(){
		
		System.out.println("eee");
		
		setBackground(Color.RED);
		setPreferredSize( new java.awt.Dimension(600,600)); 
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		System.out.println("ddd");
	}
	
	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
		
		r=new Rectangle();
		
		System.out.println("aaaaa");
		  pressedX=getX();
		  pressedY=getY();
	
		r.getpressedXY(pressedX,pressedY);
		System.out.println("zzzz");
	
		
		
	}

	public void mouseReleased(MouseEvent e) {
		
		System.out.println("yyyyy");
		   releasedX=getX();
		   releasedY=getY();
		r.getreleasedXY(releasedX,releasedY);
		
		repaint();
		
		System.out.println("ffff");

	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
	}

	
	
}
```


----------



## Wildcard (8. Jun 2005)

Wart' ein paar Minuten, dann geb ich dir 'Starthilfe'
Ich bin einfach zu nett  :wink:


----------



## Sindbad1983 (8. Jun 2005)

du lässt mich ordentlich zappeln..


aber wahrscheinlich willst du nur, dass ich selber draufkomm!?

ich bin dir trotzdem unglaublich dankbar!

Hättest sicher bessere Dinge zu tun, als einem Java-Anfänger (den ganzen Tag) zu helfen..


----------



## Wildcard (8. Jun 2005)

Das ist mal der Anfang. Die Factory musst du da jetzt selbst reinbauen :wink: 

```
/**
 * 
 */
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Wildcard
 * created at 08.06.2005
 */
public class DrawingFrame extends JFrame
{

	private DrawingPanel panel;
	
	public DrawingFrame()
	{
		panel = new DrawingPanel();
		getContentPane().add(panel);
		panel.setSize(getContentPane().getSize());
		panel.setFocusable(true);
		panel.requestFocus();
		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		DrawingFrame frame = new DrawingFrame();
		frame.setSize(500,500);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);

	}

}

class DrawingPanel extends JPanel implements MouseListener
{
	private ArrayList children = new ArrayList();
	
	private Point clickPoint;
	
	public DrawingPanel()
	{
		addMouseListener(this);
	}
	
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		drawChildren(g);
	}

	private void addFigure(Figure f)
	{
		children.add(f);
	}
	
	/**
	 * @param g
	 */
	private void drawChildren(Graphics g)
	{
		Iterator it = children.iterator();
		while (it.hasNext())
		{
			Figure child = (Figure) it.next();
			child.draw(g);
			
		}
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	 */
	public void mouseClicked(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
	 */
	public void mousePressed(MouseEvent e)
	{
		clickPoint = e.getPoint();
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
	 */
	public void mouseReleased(MouseEvent e)
	{
		MyRectangle rect = new MyRectangle();
		Rectangle bounds = new Rectangle(clickPoint);
		bounds.add(e.getPoint());
		rect.setBounds(bounds);
		addFigure(rect);
		repaint();
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
	 */
	public void mouseEntered(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
	 */
	public void mouseExited(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}
	
}


abstract class Figure
{
	protected Rectangle bounds;
	
	protected Point location;
	
	abstract public void draw(Graphics g);

	public Rectangle getBounds()
	{
		return bounds;
	}

	public void setBounds(Rectangle bounds)
	{
		this.bounds = bounds;
	}

	public Point getLocation()
	{
		return location;
	}

	public void setLocation(Point location)
	{
		this.location = location;
	}	
}

class MyRectangle extends Figure
{

	/* (non-Javadoc)
	 * @see Anfaenger.Sindbad.Figure#draw(java.awt.Graphics)
	 */
	@Override
	public void draw(Graphics g)
	{
		g.drawRect(bounds.x,bounds.y,bounds.width,bounds.height);
		
	}
	
}
```

EDIT: da ich nicht weiß welche Java Version du benutzt hab ich's mal Java 1.4 konform gemacht.


----------



## Sindbad1983 (8. Jun 2005)

boa...cool

danke..das wär aber nicht notwenig gewesen!!

Aber weißt du, wo bei mir der Fehler liegt?
Das wär auch so interessant für mich!
Da kann ja  nicht mehr viel fehlen!! oder schon?

 :roll:


----------



## Sindbad1983 (8. Jun 2005)

wahnsinn..das hast du echt klasse gemacht...
ich versteh alles..ist irgendwie ganz einfach..und trotzdem  hab ich da solche Probleme..
das wird noch ein steiniger Weg... :-(

wie lang hast du da jetzt gebraucht für?


----------



## Wildcard (8. Jun 2005)

Sindbad1983 hat gesagt.:
			
		

> Aber weißt du, wo bei mir der Fehler liegt?
> Das wär auch so interessant für mich!
> Da kann ja nicht mehr viel fehlen!! oder schon?


Ist das oben dein aktueller Code?
Du setzt die Rectangles nicht richtig auf das Panel wie schon gesagt.
Nimm lieber die Vorlage von mir, dein Code ist durch 'trial-and-error" schon etwas unsauber geworden  :wink: 



			
				Sindbad1983 hat gesagt.:
			
		

> wahnsinn..das hast du echt klasse gemacht...
> ich versteh alles..ist irgendwie ganz einfach..und trotzdem  hab ich da solche Probleme..
> das wird noch ein steiniger Weg... :-(
> 
> wie lang hast du da jetzt gebraucht für?


je größer die herausforderung, desto mehr lernt man dabei  :wink: 
so ungefähr 15 mins...


----------



## Sindbad1983 (8. Jun 2005)

dort wo ich geschrieben hab.."mensch jetzt bin ich verzweifelt"

ist mein aktueller Code

15min..wahnsinn

ich sitz schon seit 7 Stunden da und nichts geht!

Hab deins grad ausprobiert..funktioniert perfekt!

Danke!


PS:Findest du dieses Beispiel mit den Factories schwer?
ist das ein Anfängerbeispiel`?


----------



## Wildcard (8. Jun 2005)

Schwierig zu definieren was ein Anfängerbeispiel ist. Selbst zeichnen ist nie so richtig 'Anfänger'
Ausserdem programmierst du ja fast genausolange mit Java wie ich  :wink: 
Factories sind nicht wirklich kompliziert, es wird ja lediglich die Objekterzeugung ausgelagert.
Finde es aber sehr gut das ihr sinnvolle Sachen programmiert und euch auch mit Design-Patterns beschäfftigt.
Das ist nämlich viel wichtiger als Java zu können...


----------



## Sindbad1983 (8. Jun 2005)

wieso?
wielange programmierst du leicht schon?
studierst du auch?

naja..ich hab vor 2 Jahren angefangen, aber so richtig erst seit 3,4 Monaten...dazwischen immer laaaange Pausen gemacht!

Ich hab in der Schule NIE progammiert und daraus resultierend tu ich mir verhältnismäßig schwer bzw. hab immer wieder mit Verständnisproblemen bei scheinbar einfachen Dingen zu kämpfen..wie man ja unschwer erkennen kann!

Aber es wird schon besser!
Ich hab Ende Juni Klausur und bis dahin muss ich all das auf die Reihe kriegen..

..aber was würd ich ohne euch machen...


----------



## Wildcard (8. Jun 2005)

[offtopic]
Bin BA-Student, und hab mit Java im September angfangen.
Ich denke die Übungsaufgabe ist genau das richtige um etwas über gute Klassenstruktur und Swing zu lernen.
Kompliment an euren Prof!
Gerade im hinblick auf die Klausur: sieh dir meinen Code nochmal an und wenn du genau verstehst was ich gemacht
habe, und warum ich es so gelöst habe (kannst mich natürlich auch über PN fragen) fängst du an die Factory einzubauen
und das Prog Stück für Stück zu erweitern.

Viel Erfolg  :wink: 
[/offtopic]


----------



## Sindbad1983 (8. Jun 2005)

was ist jetzt eigentlich der Unterschied zu:


```
public class PaintFrame extends JFrame implements ActionListener{
	
	private Zeichenflaeche zeichenflaeche;
	
	
	public PaintFrame(String titel){
		super(titel);
		
		Container c=getContentPane();
		zeichenflaeche=new Zeichenflaeche();
		c.add(zeichenflaeche);
		zeichenflaeche.setFocusable(true); 
	    zeichenflaeche.requestFocus();
		System.out.println("bbbb");
	}
```


und 



```
public PaintFrame(String titel){
		super(titel);
		
		Container c=getContentPane();
		Zeichenflaeche zeichenflaeche=new Zeichenflaeche();
		c.add(zeichenflaeche);
		zeichenflaeche.setFocusable(true); 
	    zeichenflaeche.requestFocus();
		System.out.println("bbbb");
	}
```

bliebt sich ja eigentlich komplett wurscht, wo Zeichenflaeche deklariert wird, oder?

oder hat das schon eine Bedeutung...?


----------



## Wildcard (8. Jun 2005)

Die erste Variante wählt man wenn man in der ganzen Klasse zugriff auf die Zeichenfläche braucht, die zweite wenn das nicht nötig ist.


----------



## Sindbad1983 (8. Jun 2005)

boa..ich habs endlich geschafft, dass es mit meiner Version auch geht!

es funktioniert großartig! juhuuuuuuuuuuuuuuuuuuuuuuuuu!
Danke Wildcard!  :applaus: 


die nächsten Tage werd ich dann Schritt für Schritt versuchen, das Ding zu erweitern!

Zuerst mal werd ich Kreise und Ellipsen hinzufügen...
und dann probier ich erst mal die factory...ich muss damit beginnen, dass ich alles verstehe, was ich das so programmier!  :### 

Danke nochmal für deine tolle Hilfsbereitschaft! 
Schlaf gut,ciao


----------



## Sindbad1983 (10. Jun 2005)

Hi!

Also was ich noch nicht ganz versteh?

Warum hast du in der Klasse Zeichnflaeche eine paintComponent Methode gemacht?

Wird die da überschrieben?

..wahrscheinlich weilst ja einen super-Aufruf machst!

Aber die Klasse erbt ja nur von JPanel ...


```
protected void paintComponent(Graphics g){
		
		super.paintComponent(g);
		drawChildren(g);
	}
```


----------



## Wildcard (10. Jun 2005)

paintComponent ist die Methode die man bei allen lightweight-Swing-Komponenten (alles von von JComponent abgeleitet ist, also auch JPanel) überschreibt um zeichnen zu können.
Ich hab die Methode überschrieben damit die Figures auf das Graphics-Objekt des Panels zeichnen können.


----------



## Sindbad1983 (10. Jun 2005)

ok..is klar


und ich hab gleich noch ne Frage...



```
public void mouseReleased(MouseEvent e) 
   { 
      MyRectangle rect = new MyRectangle(); 
      Rectangle bounds = new Rectangle(clickPoint); 
      bounds.add(e.getPoint()); 
      rect.setBounds(bounds); 
      addFigure(rect); 
      repaint(); 
       
   }
```


wenn ich jetzt das ganze mit ner Oberklasse Figure mach, und dabei Rectangle und Circle davon ableite, müsste ich eigentlich nur überall statt Rectanle Figure schreiben...

nur bei mouseReleased hab ich ein Problem, weil 


```
Figure f=new Figure()
```
funktioniert ja nicht, da die Klasse abstrakt ist... :bahnhof:


----------



## Sindbad1983 (10. Jun 2005)

ok..hat sich schon erledigt..bin selber draufgekommen!

Hab einfach den KeyListener implementiert und es haut super hin!
Vielleicht ein bissl umständlich, aber es funktioniert!

Hättest du es anders? besser? eleganter gemacht?


```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.*;


public class Zeichenflaeche extends JPanel implements MouseListener, KeyListener{
	
	
	
	private ArrayList list;
	Figure f;
	int ergebnis;
	
	Point startpoint;
	
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public Zeichenflaeche(){
		
		list=new ArrayList();
		
		
		setPreferredSize( new java.awt.Dimension(600,600)); 
		this.addMouseListener(this);
		this.addKeyListener(this);
	
		
	}
	
	protected void paintComponent(Graphics g){
		
		super.paintComponent(g);
		drawChildren(g);
	}
	
	
	public void drawChildren(Graphics g){
		
		Iterator it=list.iterator();
		
		while(it.hasNext()){
			Figure child=(Figure)it.next();
			child.draw(g);
			
		}
	}
	

	public void addFigure(Figure f){
		list.add(f);
	}
	
	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
		
	
		startpoint=e.getPoint();
		
		System.out.println("zzzz");
	
	}
	
	

	public void mouseReleased(MouseEvent e) {
		
		
		switch(ergebnis){
		case 1:
			 Figure f=new Circle();
			  
			   Point zielpoint=e.getPoint();
			   f.setXY(startpoint.x, startpoint.y,zielpoint.x,zielpoint.y);
			   addFigure(f);
			   repaint();
			   break;
			  
			
			
			
		
		case 2: 
			 Figure fg=new Rectangle();
			  
			    Point zielpoint2=e.getPoint();
			   fg.setXY(startpoint.x, startpoint.y,zielpoint2.x,zielpoint2.y);
			   addFigure(fg);
			   repaint();
			   break;
			   
			
			
			
			
		}
	}
		
	
	
		

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void keyTyped(KeyEvent e) {
		
		
		
		char key=e.getKeyChar();
		
		if(key==KeyEvent.VK_ENTER){
			makeCircle();
			System.out.println("Enter");
		}
		else if(key==KeyEvent.VK_SPACE){
			makeRectangle();
			System.out.println("Leertaste");
		}
		
		
		
	}

	public void keyPressed(KeyEvent e) {	
	}

	public void keyReleased(KeyEvent e) {		
	}
	
	public int makeCircle(){
		System.out.println("makeCircle wurde aufgerufen");
		ergebnis=1;
		
		return ergebnis;
		
	}
	
	public int  makeRectangle(){
		System.out.println("makeRectangle wurde aufgerufen");
		ergebnis=2;
		return ergebnis;
	}

	
	
}
```


----------



## Wildcard (10. Jun 2005)

Je mehr du daran jetzt weiterschreibst, desto schwieriger wirds nachher die Factory einzubauen.
Nur so'n Tipp...   :wink:


----------



## Sindbad1983 (11. Jun 2005)

hast sicher Recht..

aber ich werd dann eh wieder vom Ausgangspunkt los starten..
was ich aber noch unbedingt jetzt weiter programmieren möcht ist, dass die Kreise in verschiedenen Farben dargestellt werden!

Die Farbe kann ich aber nicht in Figure speichern, weil Figure ja abstrakt ist.. jetzt fällt mir grad ein, muss die eigentlich abstarkt sein? was ist, wenn ich sie nicht abstrakt mache? dann kann ich trotzdem die Unterklassen von dieser erben lassen, oder?

Nur beim Factory-Pattern muss die Oberklasse abstrakt sein glaub ich...

oder gibts ne andere Möglichkeit, wie ich die Farbe speichern bzw. übergeben kann?
Weil bestimmt wird die Farbe ja über die MenuItems..


----------



## Sindbad1983 (11. Jun 2005)

übrigens wartet schon die nächste Übung...3 Pattern müssma da verwenden -> das wird spaßig! :-(

..ich muss mich also beeilen!

Bis dann
ciao


----------



## Wildcard (12. Jun 2005)

Natürlich kannst du die Farbe in Figure speichern (solltest du auch in jedem Fall tun).
Bis auf die Instanzierung können abstrakte Klassen alles was normale Klassen können.
OOP orientiert sich möglichst nahe am 'normalen Leben'.
Rechteck, Dreieck, Kreis sind Formen. Wenn ich dir sage "mal mir einen Kreis" kannst du das machen
Wenn ich dir allerdings sage mal "mir eine Form" bist du aufgeschmissen und malst entweder einen Kreis, ein Rechteck, oder ein Dreick.
Eine Form ist also etwas abstraktes.
Deshalb ist auch Figure abstarkt, da die Instanzierung einer Figure keinen Sinn machen würde.


----------



## Sindbad1983 (12. Jun 2005)

hi Wildcard!

Ja, das hab ich auch schon versucht, aber die Farbe kann ich in Figure nur durch

f.setColor(c) speichern oder?

Und dazu brauch ich aber f=new Figure, weil ich sonst ne NullP.E. bekomme!..

weißt du was ich mein?

PS: morgen häng ich mich wieder voll rein!
War die letzten 2 Tage auf Kurzurlaub in Innsbruck!  :toll:


----------



## Wildcard (12. Jun 2005)

nein, du brauchst eine Instanzvariable vom Typ Color (entweder einen getter einbauen oder protected machen).
Diese kannst du in Figure setzen und bei der konkreten Implementierung in der drawMethode mit g.setColor(super.color) verwenden.


----------



## Sindbad1983 (12. Jun 2005)

naja ..  Color hab ich eh als Instanzvariable in Figure gespeichert!


und die setMethode hab ich auch:


```
public void setColor(Color c){
this.c=c;
}
```


aber PaintFrame hab ich ja den KeyListener eingebaut und da wird je nach Auswahl eines MenuItems eine andere Farbe gespeichert! Die Farbe wird dann in Color von Figur gespeichert, das ist mir völlig klar!

Aber trotzdem komm ich um das f.setColor(Color.blue) nicht herum -> weil nur setColor allein genügt nicht!
Also das f. brauch ich unbedingt! Oder hab ich da jetzt nen Denkfehler drinnen? ???:L


----------



## Wildcard (12. Jun 2005)

dann versteh ich die Frage nicht!
was hat das ganze mit 'ner NullPointerException zu tun? 
 :bahnhof:


----------



## Sindbad1983 (12. Jun 2005)

naja..wie willst du etwas in ner Klasse setzen, wenn du nicht mal ein Objekt hast, in dem du etwas speichern kannst!? 
Ich bin immer davon ausgegangen, dass man zuerst eine Instanz von einer Klasse bilden muss, bevor man die Variablen mit den Methoden verändern kann (bzw. Werte mit set-Methoden) speichern kann...

Verstehst?
Also wie soll ich dann an dem Figure f=new Figure() vorbeikommen?

wenn ich die Instanzvariable Color c mit
f.setColor(Color.blue) setzen soll...

alles klar?
das ist nämlich mein Problem!

Weil wenn ich in PaintFrame einfach nur sag:

setColor(Color.blue) dann weiß er ja nicht, dass das setColor zu Figure gehört..ok?

ich hoffe, du verstehst mich jetzt...


----------



## Wildcard (12. Jun 2005)

Du kannst doch aber nicht einfach eine neue Figure erstellen wenn man die Farbe ändert  :autsch: 
Wenn der Benutzer die nächste Figure erstellt muss die Factory eben wissen welche Farbe gerade ausgewählt ist und die neue Figure dementsprechend modifizieren.


----------



## Sindbad1983 (13. Jun 2005)

Es funktioniert!!!

Tut mir leid Wildcard..da hatten wir wohl einen Kommunikationsfehler!
Ich war ja grad dabei die selbe Aufgabe zuerst mal ohne Pattern zu implementieren..
und es geht jetzt : habs mit einer eigenen Klasse und einer static Variable geschafft, die ich gesetzt hab!


Jetzt schau ich, dass ich das Pattern noch irgendwie hinbekomm...


Damit siehst, wie ichs gemacht hab:



```
public class PaintFrame extends JFrame implements ActionListener{
	
	
	private Zeichenflaeche zeichenflaeche;
	
	
	
	
	ActionListener listener;
	public PaintFrame(String titel){
		super(titel);
		
		
	
		
		zeichenflaeche=new Zeichenflaeche();
		getContentPane().add(zeichenflaeche); 
	    zeichenflaeche.setSize(getContentPane().getSize()); 
	    zeichenflaeche.setFocusable(true); 
	    zeichenflaeche.requestFocus(); 
	}
	
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 MenuItem red=new MenuItem("Red");
		 MenuItem blue=new MenuItem("Blue");
		 MenuItem green=new MenuItem("Green");
		
		 m.add(red);
		 red.addActionListener(this);
		 m.add(blue);
		 blue.addActionListener(this);
		 m.add(green);
		 green.addActionListener(this);
		 bar.add(m);
		 setMenuBar(bar);
		 System.out.println("ccc");
		 
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		
		String me=e.getActionCommand();
	
		
		
		if(me.equals("Red")){
			System.out.println("Rot wurde ausgewählt");
			Farbe.c=Color.RED;
			
		
		}
		else if(me.equals("Blue")){
			System.out.println("Blau wurde ausgewählt");
			Farbe.c=Color.BLUE;
			
		}
		else if(me.equals("Green")){
			System.out.println("Grün wurde ausgewählt");
			Farbe.c=Color.GREEN;
			
			
			
			
		}
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		
		frame.setSize(600,600);
		
		frame.setLocationRelativeTo(null); 
		frame.setVisible(true);
		frame.makeMenu();
		

		

			
	}

}
```



```
public class Zeichenflaeche extends JPanel implements MouseListener,KeyListener{
	
	
	
	private ArrayList list;
	Figure f;
	int ergebnis;
	Farbe farbe;
	
	Point startpoint;
	
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	public Zeichenflaeche(){
		
		list=new ArrayList();
		
		
		setPreferredSize( new java.awt.Dimension(600,600)); 
		this.addMouseListener(this);
		this.addKeyListener(this);
	
		
	}
	
	protected void paintComponent(Graphics g){
		
		super.paintComponent(g);
		drawChildren(g);
	}
	
	
	public void drawChildren(Graphics g){
		
		Iterator it=list.iterator();
		
		while(it.hasNext()){
			Figure child=(Figure)it.next();
			child.draw(g);
			
		}
	}
	

	public void addFigure(Figure f){
		list.add(f);
	}
	
	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
		
	
		startpoint=e.getPoint();
		
		System.out.println("zzzz");
	
	}
	
	
	

	public void mouseReleased(MouseEvent e) {
		
		
		System.out.println("Die Maus wurde gedrückt");
	
		
		switch(ergebnis){
		case 1:
			 Figure f=new Circle();
			 f.setColor(Farbe.c);
			 
			   Point zielpoint=e.getPoint();
			   f.setXY(startpoint.x, startpoint.y,zielpoint.x,zielpoint.y);
			   addFigure(f);
			   repaint();
			   break;
			  
			
			
			
		
		case 2: 
			 Figure fg=new Rectangle();
			 
			 fg.setColor(Farbe.c);
			
			  
			   Point zielpoint2=e.getPoint();
			   fg.setXY(startpoint.x, startpoint.y,zielpoint2.x,zielpoint2.y);
			   addFigure(fg);
			   repaint();
			   break;
		}
	}
	

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void keyTyped(KeyEvent e) {
		
		
		
		char key=e.getKeyChar();
		
		if(key==KeyEvent.VK_ENTER){
			makeCircle();
			System.out.println("Enter");
		}
		else if(key==KeyEvent.VK_SPACE){
			makeRectangle();
			System.out.println("Leertaste");
		}
		
		
		
	}

	public void keyPressed(KeyEvent e) {	
	}

	public void keyReleased(KeyEvent e) {		
	}
	
	public int makeCircle(){
		System.out.println("makeCircle wurde aufgerufen");
		ergebnis=1;
		
		return ergebnis;
		
	}
	
	public int  makeRectangle(){
		System.out.println("makeRectangle wurde aufgerufen");
		ergebnis=2;
		return ergebnis;
	}


	
	
}
```


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

public class Farbe {
	
    static	Color c;
	
}
```


----------



## Wildcard (13. Jun 2005)

Also das war jetzt echt die schlechteste Möglichkeit  :shock: 
Lass den Mist mit der Farbe Klasse und mach dir stattdessen in Zeichenfläche eine private Variable Color in
der die Farbauswahl steht.
Ist zwar IMHO von der Logik her an der falschen Stelle, aber bevor du solche seltsamen Konstrukte verwendest...  :wink:


----------



## Sindbad1983 (13. Jun 2005)

jaaaaaaaaaaa es funktioniert!!!


Wenn das jetzt auch die (halbigs) richtige Implementierung eines Factory-Patterns ist..??

Das mit der Farbe werd ich dann noch schnell ändern...


```
public class Zeichenflaeche extends JPanel implements MouseListener, KeyListener{
	
	
	ArrayList list;
	
	int ergebnis=0;
	Point startpoint;
	AbstractFigureFactory factory;
	
	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	
	
	public Zeichenflaeche(){
	
		
		setBackground(Color.WHITE);
		this.addMouseListener(this);
		this.addKeyListener(this);
		list=new ArrayList();
		
		
	}
	
	

	protected void paintComponent(Graphics g){
		
		super.paintComponent(g);
		drawChildren(g);
	}
	
	
	public void drawChildren(Graphics g){
		
		Iterator it=list.iterator();
		
		while(it.hasNext()){
			Figure child=(Figure)it.next();
			child.draw(g);
			
		}
	}
	
	
	public void addFigure(Figure f){
		list.add(f);
	}
	

	
	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
		
	
		startpoint=e.getPoint();
		
		System.out.println("zzzz");
	
	}
	
	
	

	public void mouseReleased(MouseEvent e) {
		
		
		System.out.println("Die Maus wurde gedrückt");
	
		
		switch(ergebnis){
		case 1:
			   factory=new CircleFactory();
			 
			   Figure f=factory.createFigure();
			 
			   f.setColor(Farbe.c);
			 
			   Point zielpoint=e.getPoint();
			   f.setXY(startpoint.x, startpoint.y,zielpoint.x,zielpoint.y);
			   addFigure(f);
			   repaint();
			   break;
			  
			
			
			
		
		case 2: 
			 factory=new RectangleFactory();
			 Figure fg=factory.createFigure();
			 
			 fg.setColor(Farbe.c);
			
			  
			   Point zielpoint2=e.getPoint();
			   fg.setXY(startpoint.x, startpoint.y,zielpoint2.x,zielpoint2.y);
			   addFigure(fg);
			   repaint();
			   break;
		}
	}
	

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void keyTyped(KeyEvent e) {
		
		
		
		char key=e.getKeyChar();
		
		if(key==KeyEvent.VK_ENTER){
			makeFigure1();
			System.out.println("Enter");
		}
		else if(key==KeyEvent.VK_SPACE){
			makeFigure2();
			System.out.println("Leertaste");
		}
		
		
		
	}

	public void keyPressed(KeyEvent e) {	
	}

	public void keyReleased(KeyEvent e) {		
	}
	
	public int makeFigure1(){
		
		ergebnis=1;
		return ergebnis;
		
	}
	
	public int  makeFigure2(){
		
		ergebnis=2;
		return ergebnis;
	}


	
	
}
```

naja..Hauptsache es geht!

Er zeichnet alle Figuren in allen Farben..wie verlangt!


----------



## Wildcard (13. Jun 2005)

Und nochmal:
Du darfst in Zeichenfläche in KEINEM FALL FABRIKEN INSTANZIEREN (Konkrete Fabriken sind sowieso Singeltons)!
Sonst könnte man sich die Factory ja direkt sparen...
Du brauchst eine konkrete Fabrik die farbige Figuren erzeugt, und eine die s/w-Figuren erzeugt wenn ich die Aufgabenstellung noch richtig im Kopf hab.
Die einzige Fabrik die du in Zeichenfläche kennen darfst ist die abstrakte Fabrik!!!


Ich glaube das sprengt hier langsam den Rahmen. Wenn du ICQ hast schreib mir mal ne PN mit deiner Nummer dann versuch ich's dir zu erklären...


----------



## Sindbad1983 (14. Jun 2005)

```
import java.awt.Color;
import java.awt.Point;

public abstract class AbstractFigureFactory {
	
	AbstractFigureFactory factory;
	
		
	
	public abstract Figure createRectangle(int x, int y, int w, int h, Color c);
	public abstract Figure createCircle(int x, int y, int w, int h, Color c);
	
	public AbstractFigureFactory getInstance(){
		return factory;
	}
	
	public void setCurrentFactory(AbstractFigureFactory factory){
		this.factory=factory;
	}
	

}
```


```
public class ColoredFactory extends AbstractFigureFactory{

	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	Color c;


	
	public Figure createRectangle(int x, int y, int w, int h, Color c) {
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
		
		return new Rectangle(pressedX,pressedY,releasedX,releasedY, c);
	}

	public Figure createCircle(int x, int y, int w, int h, Color c) {
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
		
		return new Circle(pressedX,pressedY,releasedX,releasedY, c);
	}

	
	

}
```


```
public class BlackAndWhiteFactory extends ColoredFactory {

	
	public Figure createRectangle(int x, int y, int w, int h, Color c) {
		
		if(c!=Color.black){
			System.out.println("Hier wurde eine ColorException ausgelöst");
			return null;
		}
		
		super.createRectangle(h, h, h, h, c);
		return new Rectangle(pressedX,pressedY,releasedX,releasedY, Color.black);
		
		
	}



	
	public Figure createCircle(int x, int y, int w, int h, Color c) {

		if(c!=Color.black){
			System.out.println("Hier wurde eine ColorException ausgelöst");
			return null;
		}
		
		super.createCircle(h, h, h, h, c);
		return new Circle(pressedX,pressedY,releasedX,releasedY, Color.black);
		
	}

}
```


```
public abstract class Figure {
	

	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	Color c;
	
	public abstract void draw (Graphics g);

}
```


```
public class Rectangle extends Figure {
	


	
	public Rectangle(int x, int y, int w, int h, Color c){
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
	}
	
	public void draw(Graphics g){
		g.setColor(this.c);
		g.drawRect(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
		
	}

}
```


```
public class Circle extends Figure {
	
	public Circle (int x, int y, int w, int h, Color c){
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
	}

	
	public void draw(Graphics g) {
		
		g.setColor(this.c);
		g.fillOval(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
		
		
	}

}
```


```
public class PaintFrame extends JFrame implements ActionListener{
	
	AbstractFigureFactory factory;
	private Zeichenflaeche zeichenflaeche;
	
	
	
	
	ActionListener listener;
	public PaintFrame(String titel){
		super(titel);
		
		
	
		
		zeichenflaeche=new Zeichenflaeche();
		getContentPane().add(zeichenflaeche); 
	    zeichenflaeche.setSize(getContentPane().getSize()); 
	    zeichenflaeche.setFocusable(true); 
	    zeichenflaeche.requestFocus(); 
	}
	
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 MenuItem red=new MenuItem("Red");
		 MenuItem blue=new MenuItem("Blue");
		 MenuItem green=new MenuItem("Green");
		
		 m.add(red);
		 red.addActionListener(this);
		 m.add(blue);
		 blue.addActionListener(this);
		 m.add(green);
		 green.addActionListener(this);
		 bar.add(m);
		 setMenuBar(bar);
		 System.out.println("ccc");
		 
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
                                        
            
	                    //das ist neu!!	
		factory.setCurrentFactory(new ColoredFactory());
		
		
		String me=e.getActionCommand();
	
		
		
		if(me.equals("Red")){
			System.out.println("Rot wurde ausgewählt");
			
			
			
			
		
		}
		else if(me.equals("Blue")){
			System.out.println("Blau wurde ausgewählt");
			
			
			
		}
		else if(me.equals("Green")){
			System.out.println("Grün wurde ausgewählt");
			
			
			
			
			
		}
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		
		frame.setSize(600,600);
		
		frame.setLocationRelativeTo(null); 
		frame.setVisible(true);
		frame.makeMenu();
		

		

			
	}

}
```

und natürlich Zeichenflaeche noch als eigene Klasse


----------



## Wildcard (14. Jun 2005)

Hab mir gerade nochmal die Aufgabenstellung durchgelesen. 
Dachte das Color/S/W währe vorgeben, aber das hast du dir ja rausgesucht. Ist etwas ungeschickt, da die Color-Factory schon alles leistet was die S/W kann.
Währ deshalb besser eine andere Factory zu nehmen, beispielsweise eine die die Figuren auch ausfüllt, oder dickere Striche zeichnet.
Auserdem sollten deine konkreten Factorys Singeltons sein.


```
public class ColoredFactory extends AbstractFigureFactory{

//entfern die Klassenvariablen, die sind unnötig.
   int pressedX;
   int pressedY;
   int releasedX;
   int releasedY;
   Color c;


   
   public Figure createRectangle(int x, int y, int w, int h, Color c) {
      this.pressedX=x;
      this.pressedY=y;
      this.releasedX=w;
      this.releasedY=h;
      this.c=c;
      
      return new Rectangle(pressedX,pressedY,releasedX,releasedY, c);
   }

   public Figure createCircle(int x, int y, int w, int h, Color c) {
      this.pressedX=x;
      this.pressedY=y;
      this.releasedX=w;
      this.releasedY=h;
      this.c=c;
      
      return new Circle(pressedX,pressedY,releasedX,releasedY, c);
   }
}
```


----------



## Sindbad1983 (14. Jun 2005)

```
class Zeichenflaeche extends JPanel implements MouseListener , KeyListener
{ 
   private ArrayList children = new ArrayList(); 
    
   private Point startpoint;
   private Point endpoint;
   
   int pressedX;
   int pressedY;
   int releasedX;
   int releasedY;
    
   public Zeichenflaeche() 
   { 
      addMouseListener(this); 
   } 
    
   protected void paintComponent(Graphics g) 
   { 
      super.paintComponent(g); 
      drawChildren(g); 
   } 

   private void addFigure(Figure f) 
   { 
      children.add(f); 
   } 
  
   private void drawChildren(Graphics g) 
   { 
      Iterator it = children.iterator(); 
      while (it.hasNext()) 
      { 
         Figure child = (Figure) it.next(); 
         child.draw(g); 
          
      } 
       
   } 

  
   public void mouseClicked(MouseEvent e) 
   { 
     
       
   } 

   public void mousePressed(MouseEvent e) 
   { 
      startpoint = e.getPoint(); 
      pressedX=startpoint.x;
      pressedY=startpoint.y;
       
   } 

  
   public void mouseReleased(MouseEvent e){ 
	   
	   endpoint=e.getPoint();
	   releasedX=endpoint.x;
	   releasedY=endpoint.y;
	   
      repaint(); 
       
   } 

   public void mouseEntered(MouseEvent e) 
   { 
     
   } 

   
   public void mouseExited(MouseEvent e) 
   { 
    
       
   }

   public void keyTyped(KeyEvent e) {

	
   }

   public void keyPressed(KeyEvent e) {
	   
	   char test=e.getKeyChar();
	   
	   if(test==KeyEvent.VK_ENTER){
			System.out.println("Enter");
		   addFigure(AbstractFigureFactory.getInstance().createCircle(pressedX,pressedY,releasedX,releasedY,Color.blue));
		   
	   }
	   else if(test==KeyEvent.VK_SPACE){
			System.out.println("Leertaste");
		   addFigure(AbstractFigureFactory.getInstance().createRectangle(pressedX,pressedY,releasedX,releasedY,Color.blue));
	   }
	   
	   repaint();
	   
	
	
   }

   public void keyReleased(KeyEvent e) {
	
	
   } 
    
}
```

könnte die keyPressed Methode so funktionieren?
ist das die richtige Anwendung?

als Farbe hab ich jetzt einfach mal blau genommen..da muss ich mir noch Gedanken drüber machen!
Versteh ich noch nicht ganz, wie ich das PaintFrame die ausgewählte Farbe in die keyPressed-Methode (Color c) reinbekomm...


----------



## Sindbad1983 (14. Jun 2005)

```
import java.awt.Color;
import java.awt.Point;

public abstract class AbstractFigureFactory {
	
	private static AbstractFigureFactory factory;
	Color c;
	

	
	public abstract Figure createRectangle(int x, int y, int w, int h, Color c);
	public abstract Figure createCircle(int x, int y, int w, int h, Color c);
	
	public static AbstractFigureFactory getInstance(){
		return factory;
	}
	
	public static void setCurrentFactory(AbstractFigureFactory factory){
		AbstractFigureFactory.factory=factory;
	}
	

}
```




```
public class ColoredFactory extends AbstractFigureFactory{

	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	Color c;
	
	public static final ColoredFactory INSTANCE=new ColoredFactory();
	
	public ColoredFactory(){
		
	}


	
	public Figure createRectangle(int x, int y, int w, int h, Color c) {
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
		
		return new Rectangle(pressedX,pressedY,releasedX,releasedY, c);
	}

	public Figure createCircle(int x, int y, int w, int h, Color c) {
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
		
		return new Circle(pressedX,pressedY,releasedX,releasedY, c);
	}

	
	

}
```


```
public class BlackAndWhiteFactory extends ColoredFactory {
	
	public static final BlackAndWhiteFactory INSTANCE=new BlackAndWhiteFactory();
	
	public BlackAndWhiteFactory(){
	}

	
	public Figure createRectangle(int x, int y, int w, int h, Color c) {
		
		if(c!=Color.black){
			System.out.println("Hier wurde eine ColorException ausgelöst");
			return null;
		}
		
		super.createRectangle(h, h, h, h, c);
		return new Rectangle(pressedX,pressedY,releasedX,releasedY, Color.black);
		
		
	}



	
	public Figure createCircle(int x, int y, int w, int h, Color c) {

		if(c!=Color.black){
			System.out.println("Hier wurde eine ColorException ausgelöst");
			return null;
		}
		
		super.createCircle(h, h, h, h, c);
		return new Circle(pressedX,pressedY,releasedX,releasedY, Color.black);
		
	}

}
```


```
public abstract class Figure {
	

	int pressedX;
	int pressedY;
	int releasedX;
	int releasedY;
	Color c;
	
	public abstract void draw (Graphics g);

}
```


```
public class Rectangle extends Figure {
	


	
	public Rectangle(int x, int y, int w, int h, Color c){
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
	}
	
	public void draw(Graphics g){
		g.setColor(this.c);
		g.drawRect(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
		
	}

}
```


```
public class Circle extends Figure {
	
	public Circle (int x, int y, int w, int h, Color c){
		this.pressedX=x;
		this.pressedY=y;
		this.releasedX=w;
		this.releasedY=h;
		this.c=c;
	}

	
	public void draw(Graphics g) {
		
		g.setColor(this.c);
		g.fillOval(pressedX,pressedY,releasedX-pressedX,releasedY-pressedY);
		
		
	}

}
```


```
public class PaintFrame extends JFrame implements ActionListener{
	
	AbstractFigureFactory factory;
	private Zeichenflaeche zeichenflaeche;
	
	
	
	
	ActionListener listener;
	public PaintFrame(String titel){
		super(titel);
		
		factory.setCurrentFactory(new BlackAndWhiteFactory());
		
		
	
		
		zeichenflaeche=new Zeichenflaeche();
		getContentPane().add(zeichenflaeche); 
	    zeichenflaeche.setSize(getContentPane().getSize()); 
	    zeichenflaeche.setFocusable(true); 
	    zeichenflaeche.requestFocus(); 
	}
	
	
	public void makeMenu(){
		
	MenuBar bar=new MenuBar();
		
		
		 Menu m = new Menu("Look & Feel");
		 MenuItem red=new MenuItem("Red");
		 MenuItem blue=new MenuItem("Blue");
		 MenuItem green=new MenuItem("Green");
		
		 m.add(red);
		 red.addActionListener(this);
		 m.add(blue);
		 blue.addActionListener(this);
		 m.add(green);
		 green.addActionListener(this);
		 bar.add(m);
		 setMenuBar(bar);
		 System.out.println("ccc");
		 
		 
		
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		factory.setCurrentFactory(new ColoredFactory());
		
		
		String me=e.getActionCommand();
	
		
		
		if(me.equals("Red")){
			System.out.println("Rot wurde ausgewählt");
			
			
			
			
		
		}
		else if(me.equals("Blue")){
			System.out.println("Blau wurde ausgewählt");
			
			
			
		}
		else if(me.equals("Green")){
			System.out.println("Grün wurde ausgewählt");
			
			
			
			
			
		}
		
		
	}
	
	public static void main(String [] args){
		PaintFrame frame=new PaintFrame("Zeichenprogramm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		
		frame.setSize(600,600);
		
		frame.setLocationRelativeTo(null); 
		frame.setVisible(true);
		frame.makeMenu();
		

		

			
	}

}
```


```
class Zeichenflaeche extends JPanel implements MouseListener , KeyListener
{ 
   private ArrayList children = new ArrayList(); 
    
   private Point startpoint;
   private Point endpoint;
   
   int pressedX;
   int pressedY;
   int releasedX;
   int releasedY;
    
   public Zeichenflaeche() 
   { 
      addMouseListener(this); 
      addKeyListener (this);
   } 
    
   protected void paintComponent(Graphics g) 
   { 
      super.paintComponent(g); 
      drawChildren(g); 
   } 

   private void addFigure(Figure f) 
   { 
      children.add(f); 
   } 
  
   private void drawChildren(Graphics g) 
   { 
      Iterator it = children.iterator(); 
      while (it.hasNext()) 
      { 
         Figure child = (Figure) it.next(); 
         child.draw(g); 
          
      } 
       
      
   } 

  
   public void mouseClicked(MouseEvent e) 
   { 
     
       
   } 

   public void mousePressed(MouseEvent e) 
   { 
      startpoint = e.getPoint(); 
      pressedX=startpoint.x;
      pressedY=startpoint.y;
       
   } 

  
   public void mouseReleased(MouseEvent e){ 
	   
	   endpoint=e.getPoint();
	   releasedX=endpoint.x;
	   releasedY=endpoint.y;
	   
    
       
   } 

   public void mouseEntered(MouseEvent e) 
   { 
     
   } 

   
   public void mouseExited(MouseEvent e) 
   { 
    
       
   }

   public void keyTyped(KeyEvent e) {

	
   }

   public void keyPressed(KeyEvent e) {
	   
	   char test=e.getKeyChar();
	   
	   if(test==KeyEvent.VK_ENTER){
			System.out.println("Enter");
		   addFigure(AbstractFigureFactory.getInstance().createCircle(pressedX,pressedY,releasedX,releasedY,Color.blue));
		   
	   }
	   else if(test==KeyEvent.VK_SPACE){
			System.out.println("Leertaste");
		   addFigure(AbstractFigureFactory.getInstance().createRectangle(pressedX,pressedY,releasedX,releasedY,Color.blue));
	   }
	   
	   repaint();
	   
	   
	
	
   }

   public void keyReleased(KeyEvent e) {
	
	
   } 
    
}
```


----------



## Wildcard (14. Jun 2005)

```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JPanel;

/**
 * 
 */

/**
 * @author Wildcard created at 14.06.2005
 */
class Zeichenflaeche extends JPanel
{
	private ArrayList children = new ArrayList();

	private Point startpoint;

	private Point endpoint;

	private static final int RECTANGLE = 1;

	private static final int CIRCLE = RECTANGLE + 1;

	/** per default */
	private int choice = RECTANGLE;

	int pressedX;

	int pressedY;

	int releasedX;

	int releasedY;

	public Zeichenflaeche()
	{
		addMouseListener(new MouseAdapter() {

			public void mouseReleased(MouseEvent e)
			{
				endpoint = e.getPoint();
				releasedX = endpoint.x;
				releasedY = endpoint.y;

				if (choice == RECTANGLE)
					addFigure(AbstractFigureFactory.getInstance()
							.createRectangle(pressedX, pressedY, releasedX,
									releasedY, Color.blue));
				else if (choice == CIRCLE)
					addFigure(AbstractFigureFactory.getInstance().createCircle(
							pressedX, pressedY, releasedX, releasedY,
							Color.blue));
				repaint();
			}

			public void mousePressed(MouseEvent e)
			{
				startpoint = e.getPoint();
				pressedX = startpoint.x;
				pressedY = startpoint.y;
			}

		});
		addKeyListener(new KeyAdapter() {

			public void keyTyped(KeyEvent e)
			{
				if (e.getKeyChar() == KeyEvent.VK_ENTER)
					choice = CIRCLE;
				else if (e.getKeyChar() == KeyEvent.VK_SPACE)
					choice = RECTANGLE;
			}

		});
	}

	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		drawChildren(g);
	}

	private void addFigure(Figure f)
	{
		children.add(f);
	}

	private void drawChildren(Graphics g)
	{
		Iterator it = children.iterator();
		while (it.hasNext())
		{
			Figure child = (Figure) it.next();
			child.draw(g);

		}

	}

}
```


----------

