From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100153.html | 775 +++++++++++++++++++++ 1 file changed, 775 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100153.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100153.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100153.html b/Master/Reference Architectures and Patterns/hjp5/html/k100153.html new file mode 100644 index 0000000..960c800 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100153.html @@ -0,0 +1,775 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 23 - Grafikausgabe +
+
+ + + + +

23.3 Elementare Grafikroutinen

+
+ +
+ +

+Die Klasse Graphics +stellt neben vielen anderen Funktionen auch eine Sammlung von linienbasierten +Zeichenoperationen zur Verfügung. Diese sind zur Darstellung +von einfachen Linien, Rechtecken oder Polygonen sowie von Kreisen, +Ellipsen und Kreisabschnitten geeignet. Wir wollen im folgenden jede +dieser Funktionsgruppen vorstellen und ihre Anwendung an einem Beispiel +zeigen. +

+ + + + + + + + + +
+ +

+Um nicht jeweils eine komplette Klassendefinition angeben zu müssen, +werden wir in den folgenden Beispielen jeweils nur die Implementierung +der paint-Methode +zeigen. Diese könnte dann beispielsweise in das folgende Programm +eingebettet werden (auf der DVD haben diese Dateien die Erweiterung +.inc):

+ + + + +
 Hinweis 
+
+ + +

+ + + + + +
+ +
+001 /* GrafikBeispiel.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 
+006 public class GrafikBeispiel
+007 extends Frame
+008 {
+009   public static void main(String[] args)
+010   {
+011     GrafikBeispiel wnd = new GrafikBeispiel();
+012   }
+013 
+014   public GrafikBeispiel()
+015   {
+016     super("GrafikBeispiel");
+017     addWindowListener(new WindowClosingAdapter(true));
+018     setBackground(Color.lightGray);
+019     setSize(300,200);
+020     setVisible(true);
+021   }
+022 
+023   public void paint(Graphics g)
+024   {
+025     //wird in den folgenden Beispielen überlagert
+026   }
+027 }
+
+
+GrafikBeispiel.java
+ +Listing 23.4: Rahmenprogramm für nachfolgende Beispiele

+ +

+Da die paint-Methode +in diesem Programm noch keine Ausgabeoperationen enthält, erzeugt +das Programm lediglich ein leeres Fenster mit dem Titel »Grafikbeispiel«: +

+ + +

+ +

+Abbildung 23.2: Ein einfaches Fenster

+

+ + + + + + + + + +
+ +

+Das Beispielprogramm GrafikBeispiel +ist so ungefähr der kleinstmögliche Rahmen, den man für +ein AWT-basiertes Java-Programm vorgeben kann, wenn es ein einzelnes +Fenster enthalten und beim Schließen desselben automatisch beendet +werden soll. Es besteht aus folgenden Komponenten:

+ + + + +
 Hinweis 
+
+

+ + + + +

23.3.1 Linie

+

+ + + + + +
+ +
+public void drawLine(int x1, int y1, int x2, int y2)
+
+
+
+java.awt.Graphics
+ +

+ Zieht eine Linie von der Position (x1,y1) +zur Position (x2,y2). Beide +Punkte dürfen an beliebiger Stelle im Fenster liegen, das Einhalten +einer bestimmten Reihenfolge ist nicht erforderlich. Teile der Ausgabe, +die außerhalb des darstellbaren Bereichs liegen, werden, wie +in grafikorientierten Systemen üblich, unterdrückt. + +

+Das folgende Beispiel zeichnet eine Reihe von gleich hohen Linien, +deren horizontaler Abstand durch einen Zufallszahlengenerator bestimmt +wird. Das Ergebnis hat dadurch Ähnlichkeit mit einem Barcode +(ist aber keiner): + + +

+ + + + + +
+ +
+001 /* Linien.inc */
+002 
+003 public void paint(Graphics g)
+004 {
+005   int i;
+006   int x = 80;
+007 
+008   for (i=0; i<60; ++i) {
+009     g.drawLine(x,40,x,100);
+010     x += 1+3*Math.random();
+011   }
+012 }
+
+
+Linien.inc
+ +Listing 23.5: Ausgabe von Linien

+

+ + +

+ +

+Abbildung 23.3: Ausgabe von Linien

+

+ + + + + + + + + +
+ +

+Die Methode drawLine +zeichnet Linien grundsätzlich mit einer Dicke von einem Pixel. +Die hier angezeigten unterschiedlich breiten Linien kommen dadurch +zustande, dass zwei oder mehr Linien direkt nebeneinander ausgegeben +werden. Das ist die einfachste Möglichkeit, Linien darzustellen, +die dicker als 1 Pixel sind. Leider gibt es keine einfache Möglichkeit, +gestrichelte oder gepunktete Linien zu zeichnen oder ein selbstdefiniertes +Füllmuster zu verwenden.

+ + + + +
 Hinweis 
+
+ + + + +

23.3.2 Rechteck

+

+ + + + + +
+ +
+public void drawRect(int x, int y, int width, int height)
+
+
+
+java.awt.Graphics
+ +

+ Zeichnet ein Rechteck der Breite width +und der Höhe height, dessen +linke obere Ecke an der Position (x,y) +liegt. Eine größere Breite dehnt das Rechteck nach rechts +aus, eine größere Höhe nach unten. + +

+Eine Variante von drawRect +ist die Methode drawRoundRect: +

+ + + + + +
+ +
+public void drawRoundRect(
+   int x, int y,
+   int width, int height,
+   int arcWidth, int arcHeight
+)
+
+
+
+java.awt.Graphics
+ +

+Gegenüber drawRect +sind hier die Parameter arcWidth +und arcHeight dazugekommen. +Sie bestimmen den horizontalen und vertikalen Radius des Ellipsenabschnitts, +der zur Darstellung der runden »Ecke« verwendet wird. + +

+Das folgende Beispiel zeichnet eine Kette von nebeneinanderliegenden +Rechtecken, deren Größe durch einen Zufallszahlengenerator +bestimmt wird. Der Zufallszahlengenerator entscheidet auch, ob ein +Rechteck an der Ober- oder Unterseite seines Vorgängers festgemacht +wird: + + +

+ + + + + +
+ +
+001 /* Rechtecke.inc */
+002 
+003 public void paint(Graphics g)
+004 {
+005   int x = 10, y = 80;
+006   int sizex, sizey = 0;
+007 
+008   while (x < 280 && y < 180) {
+009     sizex = 4 + (int) (Math.random() * 9);
+010     if (Math.random() > 0.5) {
+011       y += sizey;
+012       sizey = 4 + (int) (Math.random() * 6);
+013     } else {
+014       sizey = 4 + (int) (Math.random() * 6);
+015       y -= sizey;
+016     }
+017     g.drawRect(x,y,sizex,sizey);
+018     x += sizex;
+019   }
+020 }
+
+
+Rechtecke.inc
+ +Listing 23.6: Ausgabe von Rechtecken

+

+ + +

+ +

+Abbildung 23.4: Ausgabe von Rechtecken

+ + + + +

23.3.3 Polygon

+ +

+Mit Hilfe der Methode drawPolygon +ist es möglich, Linienzüge zu zeichnen, bei denen das Ende +eines Elements mit dem Anfang des jeweils nächsten verbunden +ist: +

+ + + + + +
+ +
+public void drawPolygon(int[] arx, int[] ary, int cnt)
+
+
+
+java.awt.Graphics
+ +

+drawPolygon +erwartet drei Parameter. Der erste ist ein Array mit einer Liste der +x-Koordinaten und der zweite ein Array mit einer Liste der +y-Koordinaten. Beide Arrays müssen so synchronisiert sein, +dass ein Paar von Werten an derselben Indexposition immer auch ein +Koordinatenpaar ergibt. Die Anzahl der gültigen Koordinatenpaare +wird durch den dritten Parameter festgelegt. +

+ + + + + + + + + +
+ +

+Im Gegensatz zum JDK 1.0 wird das Polygon nach Abschluss der Ausgabe +automatisch geschlossen. Falls der erste und der letzte Punkt nicht +identisch sind, werden diese durch eine zusätzliche Linie miteinander +verbunden. Soll dagegen ein nichtgeschlossenes Polygon gezeichnet +werden, so kann dazu die Methode drawPolyline +verwendet werden:

+ + + + +
 Hinweis 
+
+

+ + + + + +
+ +
+public void drawPolyline(int[] arx, int[] ary, int cnt)
+
+
+
+java.awt.Graphics
+ +

+Eine zweite Variante, Polygone zu zeichnen, besteht darin, zunächst +ein Objekt der Klasse Polygon +zu konstruieren und dieses dann an drawPolygon +zu übergeben. Polygon +besitzt zwei Konstruktoren, von denen einer parameterlos ist und der +andere dieselben Parameter wie die oben beschriebene Methode drawPolygon +besitzt: +

+ + + + + +
+ +
+public void Polygon()
+
+public void Polygon(int[] arx, int[] ary, int cnt)
+
+
+
+java.awt.Polygon
+ +

+Mit Hilfe der Methode addPoint +kann ein Polygon um weitere Punkte erweitert werden. Schließlich +kann das fertige Polygon an die Methode drawPolygon +übergeben werden, die dann wie folgt aufzurufen ist: +

+ + + + + +
+ +
+public void drawPolygon(Polygon p)
+
+
+
+java.awt.Graphics
+ +

+Das folgende Beispiel gibt den Buchstaben »F« mit Hilfe +eines geschlossenen Polygons aus: + + +

+ + + + + +
+ +
+001 /* Polygon.inc */
+002 
+003 public void paint(Graphics g)
+004 {
+005   int[] arx = {50,50,120,120,80,80,100,100,80,80};
+006   int[] ary = {170,40,40,70,70,100,100,130,130,170};
+007 
+008   g.drawPolygon(arx,ary,arx.length);
+009 }
+
+
+Polygon.inc
+ +Listing 23.7: Ausgabe eines Polygons

+

+ + +

+ +

+Abbildung 23.5: Ausgabe eines Polygons

+

+ + + + + + + + + + + +
+ +

+An diesem Beispiel läßt sich ein potentielles Problem bei +der Angabe von x- und y-Koordinaten zur Bestimmung einzelner +Punkte in einem Fenster erkennen. Obwohl das Fenster durch Aufruf +der Methode setSize +eine Größe von 300*200 Pixeln hat, ist die untere Kante +des »F« bereits sehr viel näher am unteren Rand des +Fensters, als dessen y-Wert von 170 vermuten läßt, +insbesondere, wenn man bedenkt, dass der obere Rand des Buchstabens +50 Pixel vom Fensterrand entfernt ist. Der Grund dafür ist, dass +die Größenangabe für setSize +die Größe des kompletten Fensters festlegt und damit auch +den erforderlichen Platz für die Titelleiste und gegebenenfalls +das Menü einschließt. Der zur Ausgabe zur Verfügung +stehende Client-Bereich ist daher in aller Regel deutlich kleiner. +Wir werden später noch lernen, wie die exakte Größe +des Client-Bereichs bestimmt werden kann.

+ + + + +
 Warnung 
+
+ + + + +

23.3.4 Kreis

+ +

+Die Graphics-Klasse +von Java erlaubt sowohl das Zeichnen von Kreisen als auch von Ellipsen +und Kreisabschnitten. Ein Kreis wird dabei als Spezialisierung einer +Ellipse angesehen, und beide Objekte werden mit der Methode drawOval +gezeichnet: +

+ + + + + +
+ +
+public void drawOval(int x, int y, int width, int height)
+
+
+
+java.awt.Graphics
+

+ + + + + + + + + +
+ +

+Anders als in anderen Grafiksystemen werden bei dieser Methode nicht +der Mittelpunkt und der Radius des Kreises angegeben, sondern die +übergebenen Parameter spezifizieren ein Rechteck der Größe +width und heigth, +dessen linke obere Ecke an der Position (x,y) +liegt. Gezeichnet wird dann der größte Kreis, der vollständig +in das Rechteck hineinpasst.

+ + + + +
 Hinweis 
+
+ +

+Daß diese Vorgehensweise zwar untypisch ist, aber durchaus ihre +Vorteile haben kann, zeigt das folgende Beispiel: + + +

+ + + + + +
+ +
+001 /* Kreise.inc */
+002 
+003 public void paint(Graphics g)
+004 {
+005   int r = 8;
+006   int i, j;
+007   int x, y;
+008 
+009   for (i=1; i<=10; ++i) {
+010     x = 150 - r * i;
+011     y = (int) (40 + (i - 1) * 1.7321 * r);
+012     for (j=1; j<=i; ++j) {
+013       g.drawOval(x,y,2*r,2*r);
+014       x += 2 * r;
+015     }
+016   }
+017 }
+
+
+Kreise.inc
+ +Listing 23.8: Ausgabe von Kreisen

+ +

+Das Programm gibt dabei eine Pyramide von Kreisen aus. Da die an drawOval +übergebenen Parameter bereits das umgebende Rechteck bezeichnen, +kann die Figur wie eine Pyramide aus Rechtecken dargestellt werden: +

+ + +

+ +

+Abbildung 23.6: Ausgabe von Kreisen

+ + + + +

23.3.5 Kreisbogen

+ +

+Ein Kreisbogen ist ein zusammenhängender Abschnitt der Umfangslinie +eines Kreises. Er kann mit der Methode drawArc +gezeichnet werden: +

+ + + + + +
+ +
+public void drawArc(
+   int x, int y, int width, int height,
+   int startAngle, int arcAngle
+)
+
+
+
+java.awt.Graphics
+ +

+Die ersten vier Parameter bezeichnen dabei den Kreis bzw. die Ellipse +so, wie dies auch bei drawOval +der Fall war. Mit startAngle +wird der Winkel angegeben, an dem mit dem Kreisabschnitt begonnen +werden soll, und arcAngle gibt +den zu überdeckenden Bereich an. Dabei bezeichnet ein Winkel +von 0 Grad die 3-Uhr-Position, und positive Winkel werden entgegen +dem Uhrzeigersinn gemessen. Als Einheit wird Grad verwendet +und nicht das sonst übliche Bogenmaß. + +

+Das folgende Beispiel zeichnet durch wiederholten Aufruf der Methode +drawArc +eine Ellipse mit einer gestrichelten Umfangslinie. Ein Aufruf zeichnet +dabei jeweils 4 Grad der Ellipse und läßt dann eine Lücke +von 3 Grad, bevor das nächste Stück gezeichnet wird: + + +

+ + + + + +
+ +
+001 /* KreisBoegen.inc */
+002 
+003 public void paint(Graphics g)
+004 {
+005   int line = 4;
+006   int gap = 3;
+007   int angle = 0;
+008 
+009   while (angle < 360) {
+010     g.drawArc(20,40,250,140,angle,line);
+011     angle += gap + line;
+012   }
+013 }
+
+
+KreisBoegen.inc
+ +Listing 23.9: Ausgabe von Kreisbögen

+

+ + +

+ +

+Abbildung 23.7: Ausgabe von Kreisbögen

+
+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3