14.9 Clipping-Operationen
 
Alle primitiven Zeichenoperationen wirken sich auf den gesamten Bildschirm aus und sind nicht auf bestimmte Bereiche eingeschränkt. Wenn wir Letzteres erreichen wollen, setzen wir einen so genannten Clipping-Bereich, außerhalb dessen nicht mehr gezeichnet wird. Leider war in der Vergangenheit die Implementierung dieses Clippings immer etwas anfällig gegenüber Fehlern, sodass eine falsche Zeichnung durchaus vorkommen kann. Wer da auf Nummer sicher gehen will, sollte ein Offscreen-Bild anlegen, Operationen auf diesem Image machen und dann das Bild zeichnen. Doch bleiben wir beim herkömmlichen Clipping. Dies ist eine Eigenschaft des aktuellen Graphic-Objekts. Mit der Methode clipRect(int x, int y, int width, int height) lässt sich dieser Bereich einschränken. Dann erfolgen alle Operationen in diesem Bereich. Das folgende Programm erzeugt zwei Clipping-Bereiche und füllt einen sehr großen Bereich aus, der aber nicht sichtbar ist:
Listing 14.8
ClipDemo.java
import java.awt.*;
public class ClipDemo extends Frame
{
public void paint( Graphics g )
{
Graphics gcopy = g.create();
// Clipping auf
g.clipRect( 100, 100, 100, 100 );
g.setColor( Color.orange );
g.fillRect( 0, 0, 500, 500 );
g.setColor( Color.black );
g.drawOval( 150, 100, 100, 100 );
// Zweiter Clipping-Bereich
g.clipRect( 250, 250, 50, 50 );
g.setColor( Color.blue );
g.fillRect( 0, 0, 5000, 5000 );
// Die ursprüngliche Größe zurücksetzen
gcopy.setColor( Color.yellow );
gcopy.fillRect( 50, 50, 20, 50 );
gcopy.dispose();
}
public static void main( String args[] )
{
ClipDemo cd = new ClipDemo();
cd.setSize( 400, 400 );
cd.show();
}
}
Abbildung 14.3
Clipping-Bereiche
|
Den alten Zustand für Graphics wiederherstellen
Für die Zeichenoperationen im Clipping-Bereich gibt es noch eine alternative Implementierung. Diese verzichtet auf die Kopie des Grafikkontexts mittels create() am Anfang und setzt am Schluss vor die Stelle von gcopy ein getGraphics(), mit dem sich der alte Kontext wiederherstellen lässt. Dann können wir wieder mit g.drawXXX() arbeiten und gcopy ist überflüssig. Mit dem Original können wir dann das Clipping zurücksetzen und wieder ohne Zuschnitt arbeiten. Wenn wir nach dem Clipping das Orignal nicht mehr benötigen, können wir selbstverständlich auf die Kopie verzichten.
Alternative Formen
Durch setClip() können alternativ zu den rechteckigen Formen auch beliebige Shape-Objekte die Clipping-Form vorgeben. Nachfolgende paint()-Methode benutzt als Beschnitt ein Dreieck:
Listing 14.9
ClipDemo.java
import java.awt.*;
public class ClipDemo extends Frame
{
public void paint( Graphics g )
{
Rectangle r = g.getClipBounds();
System.out.println( r );
Polygon p = new Polygon(
new int[]{200,100,300},
new int[]{100,300,300}, 3
);
g.setClip( p );
g.setColor( Color.orange );
g.fillRect( 0, 0, 500, 500 );
}
public static void main( String args[] )
{
ClipDemo cd = new ClipDemo();
cd.setSize( 400, 400 );
cd.show();
}
}
Bei alten Implementierungen funktioniert dies nicht. Auf der Konsole erscheint dann eine Fehlermeldung der folgenden Art:
java.lang.IllegalArgumentException:\ setClip(Shape) only supports Rectangle objects
Verdeckte Bereiche und schnelles Bildschirmerneuern
Clipping-Bereiche sind nicht nur zum Einschränken der Primitiv-Operationen sinnvoll. Bei Bereichsüberdeckungen in Fenstern liefern sie wertvolle Informationen über den neu zu zeichnenden Bereich. Bei einer guten Applikation wird nur der Teil wirklich neu gezeichnet, der auch überdeckt wurde. So lässt sich Rechenzeit sparen.
Beispiel Informationen über Clipping-Bereiche
public void paint( Graphics g )
{
Rectangle r = g.getClipBounds();
System.out.println( r );
}
Das Programm erzeugt etwa
java.awt.Rectangle[x=4,y=23,width=392,height=373]
java.awt.Rectangle[x=104,y=87,width=292,height=309]
java.awt.Rectangle[x=104,y=87,width=286,height=211]
java.awt.Rectangle[x=104,y=87,width=243,height=196]
java.awt.Rectangle[x=104,y=87,width=221,height=219]
java.awt.Rectangle[x=101,y=89,width=221,height=219]
...
|
|