Painting und Stroking



XML und Java ... Die Java 2D API ... Next: Textausgabe

[nach oben]


Einführung

In den bisherigen Beispielprogrammen sind uns schon des öfteren die Routinen Graphics2D.fill(Shape s) und Graphics2D.draw(Shape s) begegnet. Die Operationen, die man mit diesen Methoden ausführt, heißen Painting und Stroking. Sie werden - besonders das Stroking - in diesem Kapitel behandelt.

[nach oben]


Painting

Als Painting bezeichnet man das Füllen eines Umrisses (Shape-Objekt) mit einer Farbe (Paint-Objekt). Umrisse werden in einem Graphics2D-Objekt mit der Methode fill(Shape s) gefüllt. Die aktuelle Füllfarbe wird vorher mit setPaint(Paint p) gesetzt. Es kann sich hierbei um ein beliebiges Objekt handeln, welches das Paint-Interface implementiert.

[nach oben]


Stroking

Als Stroking bezeichnet man das Zeichen der Umrißlinie eines Shape-Objektes. Das Zeichnen der Umrißlinie erfolgt anhand eines Stroke-Objektes. Stroke ist ein Interface, daß Methoden vorschreibt, die ein konkreter Pinselstrich implementieren muß. Das Zeichnen von Umrissen geschieht mit der Graphics2D-Methode draw(Shape s). Es wird der durch die Methode setStroke(Stroke s) gesetzte Pinselstrich verwendet. Als Farbe kommt auch hier die durch setPaint(Paint p) gesetzte Farbe zur Verwendung.

[nach oben]


Stroke-Interface

Das Stroke-Interface definiert abstrakt einen Pinselstrich. Es schreibt lediglich eine Methode vor: public Shape createStrokedShape(Shape s).

Die Funktionsweise ist einfach nachzuvollziehen: Wenn die Umrißlinie eines Shape-Objektes gezeichnet werden soll, dann wird dieses Shape-Objekt von Graphics2D an createStrokedShape(Shape s) übergeben. Graphics2D erhält als Ergebnis ein Shape-Objekt, daß den Umriß mit fertig gezeichneter Umrißlinie darstellt.

Wenn z.B. ein Rechteck mit einer gestrichelten Umrißlinie gezeichnet werden soll, so wird das Rechteck von Graphics2D an die createStrokedShape(...)-Methode der jeweiligen Stroke-Implemenation übergeben. Diese wird dann ein Shape-Objekt zurückliefern, dessen Umrißlinie in diesem Fall aus abwechselnd sichtbaren und unsichtbaren Liniensegmenten besteht - einer gestrichelten Linie. createStrokedShape(...) könnte z.B. auch dafür sorgen, daß die Umrißlinie mit einer Dicke von 5 Pixeln gezeichnet wird oder daß der Umriß aus lauter Dreiecken besteht.

[nach oben]


BasicStroke

Die Klasse java.awt.BasicStroke ist eine konkrete Stroke-Implementation. Sie bietet folgende Funktionalität an:

BasicStroke hat folgende Konstruktoren:

Konstruktor Beschreibung
BasicStroke() konstruiert einen BasicStroke mit Default-Attributen
BasicStroke(float width) konstruiert einen Default-BasicStroke mit der Breite width
BasicStroke(float width, int cap, int join) konstruiert einen BasicStroke der Breite width, dem End Style cap und dem Join Style join. Die Styles werden durch in der Klasse definierte Konstanten angegeben, (s. folgendes Programmbeispiel)
BasicStroke(float width, int cap, int join, float joinlimit) konstruiert einen BasicStroke der Breite width, dem End Style cap, dem Join Style join und einem Limit joinlimit in Pixeln für den angegeben Join Style. Die Styles werden durch in der Klasse definierte Konstanten angegeben, (s. folgendes Programmbeispiel)
BasicStroke(float width, int cap, int join, float joinlimit, float[] dash, float dash_phase) wie vorheriger Konstruktor, aber mit einem Array dash, welches das Muster (in Pixeleinheiten) für die Strichelung enthält (s. Beispiel). dash_phase gibt an, daß bei der ersten Verwendung (und nur hier) von dash vom ersten Array-Wert dash_phase Pixel subtrahiert wird.

Die Verwendung von BasicStroke möchte ich anhand eines Beispieles aufzeigen. Hier werden die Verschiedenen Join Styles anhand eines V-Förmigen GeneralPath-Pfades demonstriert. Des weiteren wird ein Rechteck mit der Strichelung "30 Pixel sichtbar, 10 Pixel unsichtbar, 5 Pixel sichtbar, 10 Pixel unsichtbar" gezeichnet. Als Zeichenfarbe kommt ein zyklischer Farbverlauf von gelb nach lila zum Einsatz. (Zugriff auf die Quelle):


			public void paint(Graphics g) {				
				//Upcast --> mehr Funktionen in Graphics2D
				Graphics2D g2d=(Graphics2D)g;
				g2d.setPaint(   new GradientPaint(20,50,new Color(255,241,9),
						    		  60,50,new Color(188,9,255),
						    		  true /*zyklischer Verlauf*/ )
						);
				
				//V-förmigen Shape erstellen:
				GeneralPath vshape = new GeneralPath();
				vshape.moveTo( 20, 50 );
				vshape.lineTo( 50, 200 );
				vshape.lineTo( 80, 50 );

				//Pinselstriche mit allen möglichen Join- und Endstyles:				
				BasicStroke s1=new BasicStroke( 15, BasicStroke.CAP_BUTT,
								BasicStroke.JOIN_BEVEL );
								
				BasicStroke s2=new BasicStroke( 15, BasicStroke.CAP_ROUND,
								BasicStroke.JOIN_MITER );
								
				BasicStroke s3=new BasicStroke( 15, BasicStroke.CAP_SQUARE,
								BasicStroke.JOIN_ROUND );

				//wiederholt:
				//	Pinselstrich setzen,Malen,Koordinatentranslation,...
				g2d.setStroke(s1);
				g2d.draw(vshape);
				g2d.translate( 100, 0 );
				g2d.setStroke(s2);
				g2d.draw(vshape);
				g2d.translate( 100, 0 );
				g2d.setStroke(s3);
				g2d.draw(vshape);
				
				//Translation aufheben
				g2d.setTransform( new AffineTransform() );
				
				//---------------------------------------------------------
				
				//Rechteck mit runden Ecken erzeugen
				RoundRectangle2D dashedRect = 
					new RoundRectangle2D.Double( 20,250,500,200,40,40 );
				
				float[] dash_array=new float[4];
				dash_array[0]=30; //sichtbar
				dash_array[1]=10; //unsichtbar
				dash_array[2]=5;  //sichtbar
				dash_array[3]=10; //unsichtbar
				
				BasicStroke s4 = new BasicStroke( 
					5f, //Breite
					BasicStroke.CAP_SQUARE, //End Style
					BasicStroke.JOIN_ROUND, //Join Style
					1f, //Limit für Join
					dash_array, //Strichelung
					0 //offset in Pixeln f. Strichelung
					);
					
				g2d.setStroke( s4 ); //gestrichelter Pinselstrich setzen
				g2d.draw( dashedRect ); //gestricheltes Rechteck malen
			}
Das Ergebnis sieht wie folgt aus (mit Beschriftung):


XML und Java ... Die Java 2D API ... Zum Seitenanfang