Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Die Funktionsbibliothek
10 Threads und nebenläufige Programmierung
11 Raum und Zeit
12 Datenstrukturen und Algorithmen
13 Dateien und Datenströme
14 Die eXtensible Markup Language (XML)
15 Grafische Oberflächen mit Swing
16 Grafikprogrammierung
17 Netzwerkprogrammierung
18 Verteilte Programmierung mit RMI und Web-Services
19 JavaServer Pages und Servlets
20 Applets
21 Midlets und die Java ME
22 Datenbankmanagement mit JDBC
23 Reflection und Annotationen
24 Logging und Monitoring
25 Sicherheitskonzepte
26 Java Native Interface (JNI)
27 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Stichwort

Download:
- ZIP, ca. 12,5 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel

Java ist auch eine Insel
7., aktualisierte Auflage
geb., mit DVD (November 2007)
1.492 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1146-8
Pfeil 16 Grafikprogrammierung
Pfeil 16.1 Grundlegendes zum Zeichnen
Pfeil 16.1.1 Die paint()-Methode für das AWT-Frame
Pfeil 16.1.2 Zeichen von Inhalten mit JFrame
Pfeil 16.1.3 Auffordern zum Neuzeichnen mit repaint()
Pfeil 16.1.4 Grundbegriffe: Koordinaten, Punkte, Pixel
Pfeil 16.1.5 Die ereignisorientierte Programmierung ändert Fensterinhalte
Pfeil 16.1.6 Java 2D-API
Pfeil 16.2 Einfache Zeichenfunktionen
Pfeil 16.2.1 Linien
Pfeil 16.2.2 Rechtecke
Pfeil 16.2.3 Ovale und Kreisbögen
Pfeil 16.2.4 Polygone und Polylines
Pfeil 16.3 Zeichenketten schreiben und Fonts
Pfeil 16.3.1 Zeichenfolgen schreiben
Pfeil 16.3.2 Die Font-Klasse
Pfeil 16.3.3 Einen neuen Font aus einem gegebenen Font ableiten
Pfeil 16.3.4 Zeichensätze des Systems ermitteln
Pfeil 16.3.5 Neue TrueType-Fonts in Java nutzen
Pfeil 16.3.6 Font-Metadaten durch FontMetrics
Pfeil 16.4 Geometrische Objekte
Pfeil 16.4.1 Die Schnittstelle Shape
Pfeil 16.4.2 Kreisförmiges
Pfeil 16.4.3 Kurviges
Pfeil 16.4.4 Area und die konstruktive Flächengeometrie
Pfeil 16.4.5 Pfade
Pfeil 16.4.6 Punkt in Form, Schnitt von Linien, Abstand Punkt/Linie und Weiteres
Pfeil 16.5 Das Innere und Äußere einer Form
Pfeil 16.5.1 Farben und die Paint-Schnittstelle
Pfeil 16.5.2 Farben mit der Klasse Color
Pfeil 16.5.3 Die Farben des Systems über SystemColor
Pfeil 16.5.4 Composite und Xor
Pfeil 16.5.5 Dicke und Art der Linien von Formen bestimmen über Stroke
Pfeil 16.6 Bilder
Pfeil 16.6.1 Eine Übersicht über die Bilder-Bibliotheken
Pfeil 16.6.2 Bilder mit ImageIO lesen
Pfeil 16.6.3 Ein Bild zeichnen
Pfeil 16.6.4 Programm-Icon/Fenster-Icon setzen
Pfeil 16.6.5 Splash-Screen
Pfeil 16.6.6 Bilder im Speicher erzeugen
Pfeil 16.6.7 Pixel für Pixel auslesen und schreiben
Pfeil 16.6.8 Bilder skalieren
Pfeil 16.6.9 Schreiben mit ImageIO
Pfeil 16.6.10 Asynchrones Laden mit getImage() und dem MediaTracker
Pfeil 16.6.11 Selbst definierte Cursor
Pfeil 16.6.12 VolatileImage
Pfeil 16.7 Weitere Eigenschaften von Graphics
Pfeil 16.7.1 Eine Kopie von Graphics erstellen
Pfeil 16.7.2 Koordinatensystem verschieben
Pfeil 16.7.3 Beschnitt (Clipping)
Pfeil 16.8 Zeichenhinweise durch RenderingHints
Pfeil 16.9 Transformationen mit einem AffineTransform-Objekt
Pfeil 16.10 Drucken
Pfeil 16.10.1 Drucken der Inhalte
Pfeil 16.10.2 Bekannte Drucker
Pfeil 16.11 Grafikverarbeitung ohne grafische Oberfläche
Pfeil 16.11.1 Xvfb-Server
Pfeil 16.11.2 Pure Java AWT Toolkit (PJA)
Pfeil 16.12 Zum Weiterlesen


Galileo Computing - Zum Seitenanfang

16.7 Weitere Eigenschaften von Graphics Zur nächsten ÜberschriftZur vorigen Überschrift


Galileo Computing - Zum Seitenanfang

16.7.1 Eine Kopie von Graphics erstellen Zur nächsten ÜberschriftZur vorigen Überschrift

Das Zeichensystem übergibt an die paintXXX()-Methoden ein Graphics-Objekt, das wir zum Zeichnen oft verändern, etwa um eine Farbe für nachfolgende Operationen zu setzen. Stehen eigene Zeichenfunktion jedoch nicht am Ende der Zeichenfolge, ist es wichtig, den Grafikkontext so zu restaurieren, wie er am Anfang war, um nachfolgende Zeichenoperationen nicht zu beeinflussen. Wichtig ist dies etwa bei Swing-Komponenten, wo paint() die Methoden

  • protected void paintComponent( Graphics g )
  • protected void paintBorder( Graphics g )
  • protected void paintChildren( Graphics g )

aufruft. Nun lässt sich leicht ausmalen, was passiert, wenn unsere Funktion paintComponent() ein verhunztes Graphics-Objekt hinterlässt.

Die erste Lösung ist, sich die alten Zustände zu merken und zurückzusetzen:

Color oldColor = g.getColor(); 
g.setColor( newColor ); 
... 
g.setColor( oldColor );        // Farbe zurücksetzen

Bei wenigen Eigenschaften funktioniert das gut, doch werden es mehr, ist es sinnvoller, eine Kopie aller Zustände des Grafikkontextes vorzunehmen. Dazu dient die Funktion create(). Von großer Wichtigkeit ist hier, diesen temporären Kontext auf jeden Fall mit dispose() wieder freizugeben, um keinen Speicherplatz zu blockieren.

@Override protected void paintComponent( Graphics g ) 
Graphics gcopy = g.create();   // Kopie erfragen 
try { 
  gcopy.draw...                // Alle Zeichenoperationen über gcopy 
} 
finally { 
  gcopy.dispose();             // Kopie freigeben 
}

Ist definitiv keine Ausnahme zu erwarten, kann der try-Block entfallen.


Beispiel Beispiel Es gibt noch eine zweite Notwendigkeit, ein Graphics freizugeben, nämlich dann, wenn es mit getGraphics() von einer Komponente erfragt wurde. Die an Komponenten übergebenen Graphics-Objekte gibt das System frei, denn die Regel lautet immer: Wer Ressourcen anlegt, muss sie auch wieder freigeben.



Galileo Computing - Zum Seitenanfang

16.7.2 Koordinatensystem verschieben Zur nächsten ÜberschriftZur vorigen Überschrift

Standardmäßig liegt der Koordinatenursprung bei 0,0, also in der oberen linken Ecke. Zum Verschieben des Ursprungs an eine neue Position dient die Graphics-Funktion translate(int x, int y). Alle nachfolgenden Zeichenoperationen werden dann relativ zu x, y sein, was auch den Vorteil hat, dass negative Koordinaten bei Zeichenfunktionen möglich sind.

Da Graphics2D vor dem Zeichnen beliebige affine Transformationen anwenden kann, kommen unter Graphics2D noch einige Funktionen hinzu:

  • rotate( double theta )
  • rotate( double theta, double x, double y )
  • scale( double sx, double sy )
  • setTransform( AffineTransform Tx )
  • shear( double shx, double shy )
  • transform( AffineTransform Tx )
  • translate( double tx, double ty )

Galileo Computing - Zum Seitenanfang

16.7.3 Beschnitt (Clipping) topZur vorigen Überschrift

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. Der Beschnittbereich lässt sich mit zwei Funktionen des aktuellen Graphic-Objekts modifizieren beziehungsweise einschränken:


abstract class java.awt.Graphics

  • abstract void setClip( int x, int y, int width, int height ) Setzt den neuen Beschnittbereich, sodass gezeichnete Zeilen außerhalb des Bereichs nicht sichtbar sind.
  • abstract void clipRect( int x, int y, int width, int height ) Verkleinert den Beschnittbereich, in dem der aktuelle Bereich (getClip()) mit dem übergebenen Rechteck geschnitten wird. Wurde vorher kein Beschnittbereich festgelegt – getClip() lieferte null –, ist clipRect() mit setClip() identisch.

Das folgende Programm setzt den ersten Clipping-Bereich mit setClip(100, 100, 100, 200). Das Füllen eines sehr großen Bereichs wird dann lokal nur im Beschnittbereich ausgeführt. Anschließend verkleinert clipRect(0, 200, 150, 50) den Bereich, doch obwohl x bei 0 beginnt, hat schon setClip() ihn bei 100 gesetzt, so dass die Verbindung der beiden Bereiche (100, 100, 100, 200) geschnitten (0, 200, 150, 50) = (100, 200, 50, 50) ergibt.

Listing 16.24 com/tutego/insel/ui/graphics/ClipDemo.java

package com.tutego.insel.ui.graphics; 
 
import java.awt.*; 
import javax.swing.*; 
 
public class ClipDemo extends JPanel 
{ 
  private static final long serialVersionUID = 3020598670163407618L; 
 
  @Override protected void paintComponent( Graphics g ) 
  { 
    super.paintComponent( g ); 
 
    Graphics gcopy = g.create(); 
 
    // Clipping erstmalig setzen, auch mit clipRect() möglich 
    g.setClip( 100, 100, 100, 200 );            // setClip()!! 
 
    g.setColor( Color.ORANGE ); 
    g.fillRect( 0, 0, getWidth(), getHeight() ); 
    g.setColor( Color.BLACK ); 
    g.drawOval( 150, 100, 100, 100 ); 
 
    // Zweiter Clipping-Bereich 
    g.clipRect( 0, 200, 150, 50 );              // clipRect()! 
 
    g.setColor( Color.BLUE ); 
    g.fillRect( 0, 0, 5000, 5000 ); 
 
    // Arbeite mit der ursprünglichen Größe 
 
    gcopy.setColor( Color.GREEN ); 
    gcopy.fillRect( 50, 50, 20, 50 ); 
 
    gcopy.dispose(); 
  } 
 
  public static void main( String[] args ) 
  { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
    f.setSize( 400, 400 ); 
    f.add( new ClipDemo() ); 
    f.setVisible( true ); 
  } 
}

Abbildung 16.10 Clipping-Bereiche

Alternative Formen

Durch setClip() können alternativ zu den rechteckigen Formen auch beliebige Shape-Objekte die Clipping-Form vorgeben. Die folgende paintComponent()-Methode benutzt als Beschnitt ein Dreieck:

Listing 16.25 com/tutego/insel/ui/graphics/ClipTri.java, Ausschnitt

@Override protected void paintComponent( Graphics g ) 
{ 
  super.paintComponent( 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 ); 
}

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 Beispiel Informationen über Clipping-Bereiche:

@Override 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] 
...

Aus den Ausgaben lassen sich verschiedene Fensteroperationen ableiten: Ein fremdes Fenster wurde über das Java-Fenster geschoben, und dann wurde das fremde Fenster verkleinert.


Die Rectangle-Informationen geben Aufschluss über die Größe der neu zu zeichnenden Bereiche. Haben wir schon daran gedacht, die Information in einem Image-Objekt abzulegen, lässt sich wunderbar drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) nutzen. Hier müssen wir die Werte aus dem Rectangle auslesen und in drawImage() übertragen. getClipBounds() liefert ein Rec-tangle-Objekt, dessen Werte für drawImage() nötig sind. Da jedoch auch beliebige Formen möglich sind, liefert getClip() ein Shape-Objekt. getClipRect() ist die veraltete Methode zu getClipBounds(), sonst aber identisch. Die Methode getClipBounds(Rectangle) – eine der wenigen nicht abstrakten Methoden in Graphics – legt die Informationen im übergebenen Rectangle-Objekt ab, das auch zurückgeliefert wird. Sie ruft nur getClipBounds() auf und überträgt die vier Attribute in das Rechteck.

Im Übrigen: In der paint()-Methode ist es oft klug, mit clipRect() den Bereich einzuschränken, statt ihn mit setClip() zu setzen, denn er könnte schon relativ klein sein; setClip() könnte den Beschnittbereich größer machen und unnötige Zeichenoperationen erzwingen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück



Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de