Auf Components zeichnen: Unterschied zwischen den Versionen
K |
K |
||
Zeile 84: | Zeile 84: | ||
Um neu zeichnen zu lassen, kann die Methode repaint aufgerufen werden. | Um neu zeichnen zu lassen, kann die Methode repaint aufgerufen werden. | ||
− | + | [[Kategorie:Java]] | |
[[Kategorie:Tutorials (Java)]] | [[Kategorie:Tutorials (Java)]] | ||
[[Kategorie:Swing]] | [[Kategorie:Swing]] | ||
− |
Version vom 26. Juli 2008, 06:11 Uhr
Um Grafik in eine Component- also auch z.B. einen Frame - zu zeichnen, muss grundsätzlich die Methode public void paint (Graphics g)
überschrieben werden. Diese Methode wird von dem GUI-Thread in regelmäßigen Abständen aufgerufen. Bei Vorlage:APIsollte übrigens die Methode paintComponent überschrieben werden. Vor allem bei JFrames ist es auch wichtig, die paint-Methode der Superklasse aufzurufen:
super.paint(g);
Bei Swing-Komponenten ist zudem zu beachten, dass Swing nicht threadsicher ist, und diese aus anderen Threads nicht gezeichnet werden können, es sei denn, diese Threads wurden über die statischen Methoden aus Vorlage:APIoder mit einem SwingWorker mit dem Swing-Thread synchronisiert.
Ziemlich nutzlos ist es hingegen, über die Graphics aus Component#getGraphics zu zeichnen. Bei dem nächsten repaint wird das so gezeichnete wieder überzeichnet. Der einzige Ausweg besteht darin, die Methode update leer zu implementieren, wodurch auf die Komponente aber überhaupt nicht mehr gezeichnet würde, wenn der Frame zum Beispiel minimiert und wieder maximiert worden wäre.
Die einzige Möglichkeit, während des Programmablaufes gezeichnete Dinge permanent auf die Component zu zeichnen, besteht somit darin, alles, was gezeichnet werden soll, in einer Datenstruktur (Array, Vorlage:API, Vorlage:APIusw.) zu speichern. Dies könnte zum Beispiel so aussehen:
<code=java>import javax.swing.*; import java.util.Vector; import java.awt.*;
/**
*Dieses Component muss hinzugefügt werden. */
public class JPaintComponent extends JComponent { private Vector<PaintableObject> paints = new Vector<PaintableObject>(); paintableObjects = new Vector(); public void paintObj (PaintableObject po) { paints.add (po); } public Vector<PaintableObject> getObjects() { return paints; } public void removeObj (PaintableObject po) { paints.remove (po); } public void removeAll() { paints.removeAllElements(); } public void paintComponent (Graphics g){ for (PaintableObject po : paints){ po.update (g); } } } /**
*Nur Klassen, die von dieser Klasse abgeleitet wurden, können gezeichnet werden. */
abstract class PaintableObject { private Color actual; public PaintableObject (Color actual) { this.actual = actual; } public void setColor (Color newColor) { actual = newColor; } void update (Graphics g) { g.setColor(actual); paint (g); } public abstract void paint (Graphics g); } /**
*Beispielimplementation einer Linie. */
class PaintableLine extends PaintableObject { int x1, y1, x2, y2; public PaintableLine (Color c, int x1, int y1, int x2, int y2) { super (c); this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2; } public void paint (Graphics g) { g.drawLine (x1, y1, x2, y2); } }</code=java>
Um neu zeichnen zu lassen, kann die Methode repaint aufgerufen werden.