21.05.03 Grafische Elemente/Figuren zeichnen
Mit Texte und Bildern auf einem Canvas
können Sie nun umgehen. Oftmals ist es jedoch sinnvoller, Figuren und Elemente selbst zu zeichnen anstatt hierfür Bilder zu verwenden. U. a. weil Bilder relativ viel Speicherplatz belegen (sowohl im JAR, als auch im Arbeitsspeicher des Handys) und für jede Modifikation eines Bildes eine extra Datei benötigt wird. In Java ME können Sie zumindest Basiskomponenten wie Rechtecke und Kreise zeichnen. Wie das funktioniert lernen Sie in diesem Kapitel.
Gezeichnet wird immer über das Graphics
-Objekt, das Sie in der paint
-Methode übergeben bekommen. Dieses Objekt stellt neben den bereits bekannten Methoden (drawImage, drawString, drawChar, drawChars, setColor, setFont, fillRect
und drawRegion
) noch eine Vielzahl weiterer Methoden zum Zeichnen auf dem Canvas
bereit.
Generell gibt es meistens die Möglichkeit ein komplettes Element vollständig ausgefüllt (fillXYZ
), oder nur dessen Kontur/Rahmen (drawXYZ
) zu zeichnen. So existiert zur bereits bekannten Methode fillRect(int x, int y, int width, int height)
, die ein Rechteck komplett mit der momentan gesetzten Farbe ausfüllt, ein drawRect(int x, int y, int width, int height)
, welche nur die Begrenzungslinie (Kontur) des Rechtecks in der momentan gesetzen Farbe zeichnet. Diese können Sie auch gestrichelt anzeigen. Verwenden Sie hierzu die Methode graphics.setStrokeStyle(Graphics.DOTTED)
. Möchten Sie wieder eine durchgezogene Linie haben, rufen Sie die Methode ein weiteres Mal mit dem Wert Graphics.SOLID
auf.
protected void paint(Graphics g) { g.setColor(255, 0, 0); // Rot g.fillRect(50, 50, 100, 100); // ausgefüllt g.setColor(0, 255, 0); // Grün g.drawRect(75, 75, 100, 100); // Rahmen }
Diese Komponenten werden mit den Methoden draw/fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
gezeichnet. Die x
und y
Koordinate gibt den Ursprung des Rechtecks an, das die vollständige (360 Grad) zu zeichnenden Form umschließt. width
und height
spezifizieren die Höhe und Breite. Sind diese Größen identisch, wird ein Kreis gezeichnet, ansonsten eine Ellipse/ein Oval. Die Zeichnung der Figur beginnt (0 Grad) bei 3 Uhr und kann um startAngle
Grad im Uhrzeigersinn (negativer Wert) oder gegen den Uhrzeigersinn (positiver Wert) „verschoben“ werden. Der Kreis bzw. das Oval wird von dieser Position an für die nächsten (negativer Wert) bzw. vorhergehenden (positiver Wert) arcAngle
Grad gefüllt. Für einen kompletter Kreis oder eine komplette Ellipse muss hier folglich der Wert 360 angegeben werden.
protected void paint(Graphics g) { // Zweifarbiges Oval zeichnen g.setColor(255, 255, 255); g.fillArc(getWidth() / 2 - 20, getHeight() / 2 - 15, 40, 30, 45, 180); g.setColor(0, 0, 255); g.fillArc(getWidth() / 2 - 20, getHeight() / 2 - 15, 40, 30, 45, -180); // Umrahmen g.setColor(255, 0, 0); g.drawArc(getWidth() / 2 - 20, getHeight() / 2 - 15, 40, 30, 0, 360); // Mittiger Kreis mit einem Radius von 10 Pixeln g.setColor(255, 0, 0); g.fillArc(getWidth() / 2 - 10, getHeight() / 2 - 10, 20, 20, 0, 360); // Den Kreisbogen von 6 bis 9 Uhr markieren g.setColor(0, 255, 0); g.fillArc(getWidth() / 2 - 10, getHeight() / 2 - 10, 20, 20, -90, -90); }
Eine Linie wird auf ein Canvas
mit der Methode drawLine(int x1, int y1, int x2, int y2)
gezeichnet. x1
und y1
bilden die Startkoordinaten, x2
und y2
die Endkoordinaten. Um eine Linie einmal quer durchs Display von unten links nach oben rechts zu zeichnen, verwendet man folgenden Code:
g.drawLine(0, getHeight(), getWidth(), 0);
Rundes Rechteck
Beim Zeichnen oder Ausfüllen eines Rechtecks können Sie auch abgerundete Ecken darstellen. Diese können Sie sogar soweit abrunden, bis ein Kreis entsteht. Verwenden Sie einfach anstelle von draw/fillRect
die Methode draw/fillRoundRect
und ergänzen Sie sie am Ende um zwei weitere Parameter. Der Erste gibt den horizontalen Durchmesser der Abrundung der Ecken an, der Zweite den vertikalen Durchmesser.
g.fillRoundRect(20, 40, 150, 40, 30, 20);
Dreiecke
Möchten Sie Dreiecke auf Ihr Canvas
zeichnen, verwenden Sie die Methode draw/fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
. Dabei stellen die einzelnen x/y-Paare die Eckpunkte des Dreiecks im Koordinatensystem dar. Um bspw. ein Dreieck über das komplette Handydisplay darzustellen, welches seine Spitze mittig und oben im Canvas
hat, wird folgender Code verwendet:
g.fillTriangle(0, getHeight(), getWidth(), getHeight(), getWidth() / 2, 0);
Ein Boot zeichnen
Wenn Sie diese Techniken kombinieren, können Sie recht flexibel kleinere Szenen wie bspw. ein Boot auf dem Meer bei Nacht zeichnen.
protected void paint(Graphics g) { g.setColor(0, 0, 0); g.fillRect(0, 0, getWidth(), getHeight()); drawShip(40, 140, g); drawSea(135, g); drawSky(g); } private void drawShip(int xPos, int yPos, Graphics g) { yPos -= 60; g.setColor(200, 200, 100); g.fillRoundRect(xPos, yPos, 100, 60, 20, 60); g.setColor(0, 0, 0); g.fillRect(xPos, yPos, 100, 30); g.setColor(200, 200, 100); g.fillRect(xPos + 47, yPos - 30, 6, 60); g.setColor(255, 255, 255); g.fillArc(xPos + 23, yPos - 27, 60, 50, 90, -180); g.drawLine(xPos + 60, yPos + 20, xPos + 66, yPos + 30); g.drawLine(xPos + 61, yPos + 20, xPos + 67, yPos + 30); g.setColor(0, 0, 0); g.fillArc(xPos + 38, yPos - 25, 30, 46, 90, -180); } private void drawSea(int yPos, Graphics g) { g.setColor(100, 100, 255); g.fillRect(0, yPos, getWidth(), getHeight() - yPos); g.fillArc(5, yPos - 10, 40, 20, 180, -180); g.fillArc(80, yPos - 5, 25, 10, 180, -180); g.fillArc(140, yPos - 5, 30, 10, 180, -180); g.setColor(0, 0, 0); g.fillArc(25, yPos - 5, 20, 10, 180, -180); } private void drawSky(Graphics g) { g.setColor(255, 255, 0); g.fillTriangle(10, 20, 18, 20, 14, 28); g.fillTriangle(10, 24, 18, 24, 14, 16); g.fillTriangle(40, 30, 48, 30, 44, 38); g.fillTriangle(40, 34, 48, 34, 44, 26); g.fillTriangle(100, 25, 108, 25, 104, 32); g.fillTriangle(100, 29, 108, 29, 104, 21); g.setColor(255, 255, 200); g.fillArc(getWidth() - 40, -40, 80, 80, -90, -90); g.setColor(100, 100, 100); g.drawArc(getWidth() - 16, 9, 5, 5, 0, 360); g.drawArc(getWidth() - 35, -2, 7, 7, 0, 360); g.drawArc(getWidth() - 5, 20, 8, 8, 0, 360); g.drawArc(getWidth() - 15, 30, 4, 4, 0, 360); g.drawArc(getWidth() - 5, 0, 3, 3, 0, 360); }
Mit ein bisschen künstlerischem Talent, bekommen Sie diese Szene bestimmt auch schöner hin als ich.