# Objekte in GUI verknüpfen



## GeeO (5. Mai 2012)

Hallo zusammen,

sehr schönew Forum, mein erster Beitrag!

Ich bin gerade dabei eine Java Anwendung zu planen. Es soll darum gehen, dass der Anwender die Möglichkeit hat verschiedene Objekte miteinader zu verknüpfen. Objekte teilen sich auf in grafische Objekte oder Aktionen, die auf die grafischen Objekte angewendet werden können.

Als Beispiel könnte man sich das so vorstellen:


Benutzer wählt ein Kreis Objekt. 
In einer Ausgabe wird ein Kreis gezeigt.
Benutzer verbindet das Kreis Objekt mit einem Gridobjekt.
In der AUsgabe sieht man mehrere in einem Gitter angeordnete Kreise.
Benutzer verbindet das Gridobjekt mit einem Rotationsobjekt.
Die Ausgabe des Gridobjekt fängt an zu rotieren.

Ich hoffe es ist einigermassen klar geworden  Ich möchte Objekte möglichst flexibel miteinander verknüpfen können. Hauptbestandteil sind natürlich die grafischen Objekte. Ohne diese, keine Ausgabe.

Vielleicht hat jemand nen Tipp für mich, für ein flexibles Design um Objekt in vielen Kombinationen miteinander verknüpfen zu können.
Ich dachte vielleicht ans Decorator Pattern, Aktionen könnten dann als Strategy implementiert werden.

Noch hab ich leider nicht viel zu zeigen. Es geht in erster Linie auch darum ein paar Hinweise für die Architektur zu bekommen, um nachher nicht in Teufelsküche zu kommen.

Jemand eine Idee? Bin für jeden Tipp dankbar 

Viele Grüße 
GeeO


----------



## JohannisderKaeufer (6. Mai 2012)

Von den GoF - Pattern ist hier das Decorator pattern jenes welches angeschaut werden sollte.

Decorator pattern - Wikipedia, the free encyclopedia


----------



## JohannisderKaeufer (6. Mai 2012)

Hab mal selbst versucht sowas zu bauen siehe Screenshot







Wenn man sich ein wenig mit Swing beschäftigt und sich an das Decoratorpattern hält, dann ist das fast ein Selbstläufer.

In dem Beispiel habe ich einen Kreis, der in einem Grid 2 x 2verpackt ist und dieses Grid ist widerum in einem solchen Grid. Was schlußendlich 16 Kreise geben soll.


[OT]Kann man seine Beiträge nicht mehr editieren?[/OT]


----------



## GeeO (6. Mai 2012)

Hey,

vielen Dank für deine Hilfe! Sieht wirklich schon nachdem aus, was ich mir vorgestellt habe!
Genauso, echt cool!

Vllt kannst du mir nen bisschen mehr von dem Code zeigen?
Wäre nen super Anfangspunkt für mich!

Viele Grüße
GeeO


----------



## GeeO (8. Mai 2012)

Sorry für den double Post, aber ich hänge leider und komm nicht weiter!

Ich weiß, dass ich eine Art Konkatenation der Drawing Kommandos erreichen muss,
aber leider will es nicht klappen! Es wäre echt super, wenn du mir nen bisschen mehr 
von deinem Beispiel zeigen könntest!!

Gruß und vielen Dank
GeeO


----------



## JohannisderKaeufer (8. Mai 2012)

Man benötigt schon ein paar Grundkenntnisse bezüglich Swing.

Bei Swing sollte man dazu neigen nicht direkt zu zeichnen, sondern in einen Buffer.
Zeichnet man beispielsweise eine Person in einem Raum, dann würde man immer wieder kurz einen leeren Raum sehen in dem dann die Person auftaucht.

Daher versucht man in ein BufferedImage zu zeichnen und dieses dann, sobald es fertig gezeichnet ist, auf dem Bildschirm anzuzeigen. Darüber läßt sich einiges finden. Passende Suchbegriffe sind BufferedImage, flickering, bufferstrategy,


Um also zu die "zeichenkommandos" zu verbinden habe ich in diesem Beispiel, das BufferedImage, auf das gezeichnet werden soll weitergereicht.

Als DecoratorPattern umgesetzt kommt dann in etwa sowas raus.

```
public interface Shape{
draw(BufferedImage);
}


public abstract class ShapeDecorator implements Shape{
protected Shape shape;
protected ShapeDecorator(Shape shape){
  this.shape = shape;
}
}
```

Steht so, fast 1 zu 1 bei Wikipedia (Coffee-Beispiel)


```
public Circle implements Shape{
public void Draw(BufferedImage image){
  Graphics2D g = (Graphics2D) image.getGraphics();
  g.setColor(Color.RED);
  g.drawOval(0,0,image.getWidth(), image.getHeight());
}
}

public Grid extends ShapeDecorator{
protected Grid(Shape shape)
super(shape);
}
public void Draw(BufferedImage image){
  BufferedImage b = new BufferedImage(image.getWidth()/2, image.getHeight()/2, image.getType());
  shape.draw(b);
  Graphics2D g = (Graphics2D) image.getGraphics();
  g.drawImage(b,0,0,b.getWidth, b.getHeight,null);
  g.drawImage(b,b.getWidth,0,b.getWidth, b.getHeight,null);
  g.drawImage(b,0,b.getHeight,b.getWidth, b.getHeight,null);
  g.drawImage(b,b.getWidth,b.getHeight,b.getWidth, b.getHeight,null);
}
}
```

Eigentlich nur das zeichnen eines Kreises in ein übergebenes BufferedImage und bei Grid, das erstellen von einem BufferedImage das nur 1/4 so groß ist wie das übergebene um dieses dann an shape weiterzureichen, damit der Kreis gezeichnet werden kann um diese dann in Form eines Grids zu zeichnen.

Und am Schluß braucht es noch eine Komponente die Shapes zeichnen kann


```
public ShapeComponent extends JPanel{
private Shape shape;
public ShapeComponent(Shape shape){
  this.shape = shape;
}
@Override
public void paintComponent(Graphics g){
  BufferedImage bi = new BufferedImage(getWidth(),getHeight(), BufferedImage.int_type_argb);
  shape.draw(bi);
  Graphics2D g2d = (Graphics2d) g;
  g.drawImage(bi,0,0,null);
}
}
```

Alles irgendwie recht stright forward. Den einzigen Fehler, der bei sowas gemacht werden kann ist das Graphics Objekt an eine andere Klasse weiterzugeben, weil man dann irgendwann in einer Klasse Kreis ein Graphics hat und damit einen Kreis zeichnen sollte, aber überhaupt keine Ahnung hat, wie Groß dieser werden soll, und wo er später landen soll. Bei den BufferedImages muß lediglich ein Kreis auf das BufferedImage entspechend der größe selbiges gezeichnet werden. Die Aufrufende Klasse kümmert sich dann darum wo, der Kreis dann letztendlich hingesetzt wird.


----------



## GeeO (10. Mai 2012)

Vielen Dank,

super Einstiegspunkt für mich! Besser hätte man es nicht erklären können.


----------

