# zwei JComponente gleichzeitig auf JPanel hinzufügen



## noch_anfänger (1. Jun 2010)

Hallo,
ich zeichne geometrische Fuguren an der JPanel mit graphics. Die Klassen für die Figuren sehen etwa so aus:

```
public class PaintTriangle extends JComponent{
    
    private int x;
    private int y;
    private int width;
    private int height;
    
    public PaintTriangle(int x, int y, int width, int height) {
	this.x = x;
	this.y = y;
	this.width = width;
	this.height = height;
	
    }
    
    public void paint(Graphics g) {
	int left = 30;
	int top = getHeight() - 30;

	g.translate(left, top);
	 
	g.drawLine(x, y, x + width, y); // Die horizontale Linie
	g.drawLine(x, y, x + (width / 2), y - height); // links
	g.drawLine(x + (width / 2), y - height, x + width, y); // rechts
    }
}
```

Sie werden an der JPanel so gezeichnet:

```
if(woodButton.isSelected() && holzButton.isSelected()) {
             PaintTriangle triangle = new PaintTriangle(spin2*STEP-5, 5, 10, 10);
		    PaintStoerobjekt objekt = new PaintStoerobjekt(spin1*STEP, 0, spin1*STEP, -(tabHolz.getHeight()/2) );
		    tabHolz.add(rhomb);
		    tabHolz.revalidate();
		    tabHolz.repaint();
		    tabHolz.add(objekt);
		    tabHolz.revalidate();
		    tabHolz.repaint();
}
```

Das Problem ist, dass nur das letzte JComponent wird angezeichnet, in diesem Fall 
	
	
	
	





```
object
```
. Ich brauche aber zwei. Wie kann ich das machen????:L


----------



## Gast2 (1. Jun 2010)

1. paintComponent überschreiben
2. Kommt es auf deinen LayoutManager an. Meine Glaskugel sagt mit du benutzt ein BorderLayout...


----------



## noch_anfänger (1. Jun 2010)

SirWayne hat gesagt.:


> Meine Glaskugel sagt mit du benutzt ein BorderLayout...



Stimmt!
Ein anderes nehmen?


----------



## Gast2 (1. Jun 2010)

Je nachdem was du vorhast...
weiß es ja nicht musst halt eins in Center setzen und des andere ins South.


----------



## noch_anfänger (1. Jun 2010)

Zuerst wird das Koordinatensystem gezeichnet. Und dann kommen auch weitere Zeichnungen auf das JPanel an. Ich will bei bestimmten Bedingungen gleichzeitig zwei Bildchen zeichnen können.
Mit CENTER und SOUTH wird es irgendwie unzureichend. Oder ich verstehe nicht, was du meinst.


----------



## Michael... (1. Jun 2010)

Du könntest eine JComponent nehmen auf die Du alle Objekt zeichnest bzw. zeichnen lässt. Es muss ja nicht jedes Objekt eine eigene Komponente besitzen?


----------



## noch_anfänger (1. Jun 2010)

Die Objekte, die ich zeichne, sind als 
	
	
	
	





```
extends JComponent
```
 definiert.
Wenn ich sie zeichnen lasse, füge ich sie mit 
	
	
	
	





```
tabHolz.add(triangle)
```
 zu JPanel hunzu.


```
tabHolz.add(triangle, BorderLayout.SOUTH)
```
 hilft auch nicht.


----------



## noch_anfänger (1. Jun 2010)

Auf solche Weise geht evtl. nicht, zwei JComponente gleichzeitig zu JPanel hinzufühgen...
Wie konnte man am einfachsten eine Klasse (NichtExtendsJcomponent ) für die vertikale Linien erstellen, um diese dann auf Jpanel zu zeichnen?


----------



## Marco13 (1. Jun 2010)

Michael... hat gesagt.:


> Du könntest eine JComponent nehmen auf die Du alle Objekt zeichnest bzw. zeichnen lässt. Es muss ja nicht jedes Objekt eine eigene Komponente besitzen?



Genau!

_Wie konnte man am einfachsten eine Klasse (NichtExtendsJcomponent ) für die vertikale Linien erstellen,_...

```
interface Paintable
{
    public void paintOn(Graphics g);
}

class Dreieck implements Paintable
{
    public void paintOn(Graphics g) { male Dreieck auf g }
}

class PaintPanel extends JPanel
{
    private List<Paintable> paintables = new ArrayList<Paintable>(); // add/remove-Methoden dafür

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        for (Paintable p : paintables) paintable.paintOn(g);
    }
}
```

Zu dem PaintPanel kann man dann beliebig viele "Paintable" Objekte (z.B. eben Dreiecke) hinzufügen.


----------



## Michael... (1. Jun 2010)

Folgend mal ein grobes Konzept wie ich es in etwa machen würde:
- eine Klasse die von JComponent erbt um zu zeichnen, sie enthält eine Liste in der die zu zeichnenden Objekte abgelegt werden
- ein Interface das alle Objekte die gezeichnet werden wollen erben müssen
- eine Bsp Klasse, die das Interface implementiert

```
class PaintingComponent extends JComponent {
	private List<Drawable> drawingObjects;
	{ // Dummy Initialisierung
		drawingObjects = new ArrayList<Drawable>();
		drawingObjects.add(new MyLine());
	}
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		for (Drawable dr : drawingObjects)
			dr.paint(g);
	}
}

interface Drawable {
	public void paint(Graphics g);
}

class MyLine implements Drawable {
	private int x1 = 50, x2 = 200, y1 = 50, y2 = 50;
	public void paint(Graphics g) {
		g.drawLine(x1, y1, x2, y2);
	}
}
```


----------



## Michael... (1. Jun 2010)

Mist, wieder mal zu langsam ;-)


----------



## Gast2 (1. Jun 2010)

Gibts dafür nicht schon das Shape interface????


----------



## noch_anfänger (1. Jun 2010)

Soll ich dann für jedes "Paintable"-Objekt eigene add- und remove-Methoden erstellen?
Beispiel vielleicht?


----------



## Gast2 (1. Jun 2010)

Also wenn du wirklch nur zeichnen willst, würde ich sowas machen


```
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;


public class PaintPanel extends JPanel
{

	List<Shape> list = new ArrayList<Shape>();
	
	public PaintPanel() {
		super();
		list.add(new Line2D.Double(0, 0, 200, 200));
		list.add(new Rectangle2D.Double(0, 50, 200, 200));
		setPreferredSize(new Dimension(250,300));
	}
	
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D graphics2d = (Graphics2D) g;
		for(Shape shape : list){
			graphics2d.draw(shape);
		}
	}
	
		
}
```


----------



## noch_anfänger (1. Jun 2010)

Warum soll ich 
	
	
	
	





```
list.add(PaintableObjekt)
```
 im Konstruktor machen? Objekte müssen nicht alle auf ein einziges Mal gezeichnet werden... Ich will public Methoden dafür.


----------



## Marco13 (1. Jun 2010)

```
class PaintPanel extends JPanel
{
    private List<Paintable> paintables = new ArrayList<Paintable>(); // add/remove-Methoden dafür

    public void addPaintable(Paintable paintable)
    {
        paintables.add(paintable);
    }
    public void removePaintable(Paintable paintable)
    {
        paintables.remove(paintable);
    }
 
    ...
```

:bahnhof:

@SirWayne: Solange das zu Zeichnende Objekt nicht z.B. zwei Farben enthält, ist Shape natürlich OK. (Oder präziser: Shape ist OK, wenn man nur Shapes zeichnen will )


----------



## Gast2 (1. Jun 2010)

Jop stimmt ... aber er macht ja auch nichts anderes ^^...

Ja ich würde die shapes auch eher in den einzelnen Componenten benutzen...


----------



## noch_anfänger (1. Jun 2010)

Cool! Es werden zwei Bildchen gleichzeitig gezeichnet!

Noch eine Frage: wie kann man eine gestrichelte Linie zeichnen? Keine richtige Shape, einfache Linie. (evtl. mit Graphics2D?)


----------



## Ebenius (2. Jun 2010)

Stroking and Filling Graphics Primitives (The Java™ Tutorials > 2D Graphics > Working with Geometry)

Ebenius


----------



## noch_anfänger (2. Jun 2010)

:toll:


----------



## noch_anfänger (2. Jun 2010)

Lieber Ebenius,

ich habe ein Problemchen mit 
	
	
	
	





```
dashed BasicStroke
```
: nach dem ich ein Objekt mit 
	
	
	
	





```
dashed BasicStroke
```
 zeichne, werden alle andere Objekte auch gestrichelt gezeichnet. Soll man das "abschalten"? Warum passiert sowas?


----------



## Ebenius (2. Jun 2010)

So:

```
final Graphics2D g2d = g.create();
try {
  // stroke setzen
  // zeichnen
} finally {
  g2d.dispose();
}
```
Warum? Weil man die Eigenschaften des Graphics-Objektes verändert. Jedes andere Objekt das mit diesem Objekt gezeichnet wird hat diese Eigenschaften dann auch, es sei denn es verändert sie wieder. Grundsätzlich: Alles -- außer vielleicht Color -- was man am Graphics-Objekt ändert muss man wieder zurück setzen. Oder aber -- wie oben -- auf einer Kopie arbeiten.

Ebenius


----------



## noch_anfänger (2. Jun 2010)

Danke!


----------

