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

Inhaltsverzeichnis
Vorwort
1 Neues in Java 7
2 Threads und nebenläufige Programmierung
3 Datenstrukturen und Algorithmen
4 Raum und Zeit
5 Dateien, Verzeichnisse und Dateizugriffe
6 Datenströme
7 Die eXtensible Markup Language (XML)
8 Dateiformate
9 Grafische Oberflächen mit Swing
10 Grafikprogrammierung
11 Netzwerkprogrammierung
12 Verteilte Programmierung mit RMI
13 RESTful und SOAP Web-Services
14 JavaServer Pages und Servlets
15 Applets
16 Datenbankmanagement mit JDBC
17 Technologien für die Infrastruktur
18 Reflection und Annotationen
19 Dynamische Übersetzung und Skriptsprachen
20 Logging und Monitoring
21 Java Native Interface (JNI)
22 Sicherheitskonzepte
23 Dienstprogramme für die Java-Umgebung
Stichwort

Download:
- openbook, ca. 21,3 MB
Buch bestellen
Ihre Meinung?

Spacer
Java 7 - Mehr als eine Insel von Christian Ullenboom
Das Handbuch zu den Java SE-Bibliotheken
Buch: Java 7 - Mehr als eine Insel

Java 7 - Mehr als eine Insel
Galileo Computing
1433 S., 2012, geb.
49,90 Euro, ISBN 978-3-8362-1507-7
Pfeil 10 Grafikprogrammierung
Pfeil 10.1 Grundlegendes zum Zeichnen
Pfeil 10.1.1 Die paint()-Methode für das AWT-Frame
Pfeil 10.1.2 Zeichnen von Inhalten auf ein JFrame
Pfeil 10.1.3 Auffordern zum Neuzeichnen mit repaint()
Pfeil 10.1.4 Java 2D-API
Pfeil 10.2 Einfache Zeichenmethoden
Pfeil 10.2.1 Linien
Pfeil 10.2.2 Rechtecke
Pfeil 10.2.3 Ovale und Kreisbögen
Pfeil 10.2.4 Polygone und Polylines
Pfeil 10.3 Zeichenketten schreiben und Fonts
Pfeil 10.3.1 Zeichenfolgen schreiben
Pfeil 10.3.2 Die Font-Klasse
Pfeil 10.3.3 Einen neuen Font aus einem gegebenen Font ableiten
Pfeil 10.3.4 Zeichensätze des Systems ermitteln *
Pfeil 10.3.5 Neue TrueType-Fonts in Java nutzen
Pfeil 10.3.6 Font-Metadaten durch FontMetrics *
Pfeil 10.4 Geometrische Objekte
Pfeil 10.4.1 Die Schnittstelle Shape
Pfeil 10.4.2 Kreisförmiges
Pfeil 10.4.3 Kurviges *
Pfeil 10.4.4 Area und die konstruktive Flächengeometrie *
Pfeil 10.4.5 Pfade *
Pfeil 10.4.6 Punkt in einer Form, Schnitt von Linien, Abstand Punkt/Linie *
Pfeil 10.5 Das Innere und Äußere einer Form
Pfeil 10.5.1 Farben und die Paint-Schnittstelle
Pfeil 10.5.2 Farben mit der Klasse Color
Pfeil 10.5.3 Die Farben des Systems über SystemColor *
Pfeil 10.5.4 Composite und Xor *
Pfeil 10.5.5 Dicke und Art der Linien von Formen bestimmen über Stroke *
Pfeil 10.6 Bilder
Pfeil 10.6.1 Eine Übersicht über die Bilder-Bibliotheken
Pfeil 10.6.2 Bilder mit ImageIO lesen
Pfeil 10.6.3 Ein Bild zeichnen
Pfeil 10.6.4 Programm-Icon/Fenster-Icon setzen
Pfeil 10.6.5 Splash-Screen *
Pfeil 10.6.6 Bilder im Speicher erzeugen *
Pfeil 10.6.7 Pixel für Pixel auslesen und schreiben *
Pfeil 10.6.8 Bilder skalieren *
Pfeil 10.6.9 Schreiben mit ImageIO
Pfeil 10.6.10 Asynchrones Laden mit getImage() und dem MediaTracker *
Pfeil 10.7 Weitere Eigenschaften von Graphics *
Pfeil 10.7.1 Eine Kopie von Graphics erstellen
Pfeil 10.7.2 Koordinatensystem verschieben
Pfeil 10.7.3 Beschnitt (Clipping)
Pfeil 10.7.4 Zeichenhinweise durch RenderingHints
Pfeil 10.7.5 Transformationen mit einem AffineTransform-Objekt
Pfeil 10.8 Drucken *
Pfeil 10.8.1 Drucken der Inhalte
Pfeil 10.8.2 Bekannte Drucker
Pfeil 10.9 Benutzerinteraktionen automatisieren, Robot und Screenshots *
Pfeil 10.9.1 Der Roboter
Pfeil 10.9.2 Automatisch in die Tasten hauen
Pfeil 10.9.3 Automatisierte Mausoperationen
Pfeil 10.9.4 Methoden zur Zeitsteuerung
Pfeil 10.9.5 Bildschirmabzüge (Screenshots)
Pfeil 10.9.6 Funktionsweise und Beschränkungen
Pfeil 10.9.7 MouseInfo und PointerInfo
Pfeil 10.10 Zum Weiterlesen

Galileo Computing - Zum Seitenanfang

10.5 Das Innere und Äußere einer FormZur nächsten Überschrift

Vor dem Zeichnen sammelt das Grafiksystem die Objekte in einem Kontext. Er bestimmt für die Form den Zeichenbereich (engl. clipping), die Transformationen, die Komposition von Objekten. Die diversen drawXXX()- und fillXXX()-Methoden von Graphics2D berücksichtigen beim Zeichnen Farb- und Texturangaben, Dicken der Umrisslinien, Linienmuster und Weiteres. Unterscheiden müssen wir zwischen zwei Eigenschaften:

  • Umrisslinie (Stroke): Bestimmt zum Beispiel die Dicke der Umrisslinie oder das Zeichenmuster.
  • Füllung (Paint): Wählt dazu etwa Farbe oder Verläufe.

Galileo Computing - Zum Seitenanfang

10.5.1 Farben und die Paint-SchnittstelleZur nächsten ÜberschriftZur vorigen Überschrift

Die Farben für das Innere geben Objekte vom Typ java.awt.Paint an. Paint ist eine Schnittstelle, die unter anderem folgende Klassen aus dem java.awt-Paket implementieren:

  • Color: Repräsentiert sRGB-Farben und Alpha-Werte (Transparenz).
  • GradientPaint, LinearGradientPaint, RadialGradientPaint: Füllt Formen (Shape-Objekte) mit Farbverläufen.
  • TexturePaint: Füllt Formen mit einer Textur.
  • SystemColor: Repräsentiert Farben, wie sie vom Benutzer in den Systemeinstellungen definiert sind.

Zur Zuweisung eines Paint-Objekts auf den aktuellen Graphics2D-Kontext dient die Methode setPaint(Paint). Insbesondere für Farben findet sich auch die Methode setColor(). Der Grund für diesen Unterschied ist, dass Paint erst später in Java 2 einzog.

Die Schnittstelle Paint selbst erweitert die Schnittstelle Transparency und gibt auf diese Weise an, dass alles, was gezeichnet werden kann, über Transparenz-Informationen verfügt. Die einzige Methode ist getTransparency(), und sie liefert Werte der Konstanten BITMASK, OPAQUE und TRANSLUCENT.


Galileo Computing - Zum Seitenanfang

10.5.2 Farben mit der Klasse ColorZur nächsten ÜberschriftZur vorigen Überschrift

Der Einsatz von Farben und Transparenzen ist in Java-Programmen dank der Klasse java.awt.Color einfach. Ein Color-Objekt repräsentiert üblicherweise einen Wert aus dem sRGB-Farbraum (Standard-RGB), kann aber auch andere Farbräume über den Basistyp java.awt.color.ColorSpace darstellen (wir werden das nicht weiter verfolgen).

Die Klasse Color stellt Konstanten für Standard-Farben und einige Konstruktoren sowie Anfragemethoden bereit. Außerdem gibt es Methoden, die abgewandelte Color-Objekte liefern – das ist nötig, da Color-Objekte wie String oder File immutable sind.

class java.awt.Color
implements Paint, Serializable
  • Color(float r, float g, float b)
    Erzeugt ein Color-Objekt mit den Grundfarben Rot, Grün und Blau. Die Werte müssen im Bereich 0.0 bis 1.0 liegen, sonst folgt eine IllegalArgumentException.
  • Color(int r, int g, int b)
    Erzeugt ein Color-Objekt mit den Grundfarben Rot, Grün und Blau. Die Werte müssen im Bereich 0 bis 255 liegen, sonst folgt eine IllegalArgumentException.
  • Color(int rgb)
    Erzeugt ein Color-Objekt aus dem rgb-Wert, der die Farben Rot, Grün und Blau kodiert. Der Rotanteil befindet sich unter den Bits 16 bis 23, der Grünanteil in 8 bis 15 und der Blauanteil in 0 bis 7. Da ein Integer immer 32 Bit breit ist, ist jede Farbe durch 1 Byte (8 Bit) repräsentiert. Die Farbinformationen werden nur aus den 24 Bit genommen. Sonstige Werte werden einfach nicht betrachtet und mit einem Alpha-Wert gleich 255 überschrieben.
  • Color(int r, int g, int b, int a)
  • Color(float r, float g, float b, float a)
    Erzeugt ein Color-Objekt mit Alpha-Wert für Transparenz.
  • static Color decode(String nm) throws NumberFormatException
    Liefert die Farbe von nm. Die Zeichenkette ist hexadezimal als 24-Bit-Integer kodiert, etwa #00AAFF. Eine Alternative ist new Color(Integer.parseInt(colorHexString, 16));.
Hinweis

Menschen unterscheiden Farben an den drei Eigenschaften Farbton, Helligkeit und Sättigung. Die menschliche Farbwahrnehmung kann etwa zweihundert Farbtöne unterscheiden. Diese werden durch die Wellenlänge des Lichts bestimmt. Die Lichtintensität und Empfindlichkeit unserer Rezeptoren lässt uns etwa fünfhundert Helligkeitsstufen unterscheiden. Bei der Sättigung handelt es sich um eine Mischung mit weißem Licht. Hier erkennen wir etwa zwanzig Stufen. Unser visuelles System kann somit ungefähr zwei Millionen (200 × 500 × 20) Farbnuancen unterscheiden.

Zufällige Farbblöcke zeichnen

Um die Möglichkeiten der Farbgestaltung einmal zu beobachten, betrachten wir die Ausgabe eines Programms, das Rechtecke mit wahllosen Farben anzeigt:

Listing 10.11: com/tutego/insel/ui/graphics/ColorBox.java

package com.tutego.insel.ui.graphics;

import java.awt.*;
import java.util.Random;
import javax.swing.*;

public class ColorBox extends JPanel
{
private static final long serialVersionUID = –2294685016438617741L;
private static final Random r = new Random();

@Override
protected void paintComponent( Graphics g )
{
super.paintComponent( g );

for ( int y = 12; y < getHeight() – 25; y += 30 )
for ( int x = 12; x < getWidth() – 25; x += 30 )
{
g.setColor( new Color( r.nextInt(256), r.nextInt(256), r.nextInt(256) ) );
g.fillRect( x, y, 25, 25 );
g.setColor( Color.BLACK );
g.drawRect( x – 1, y – 1, 25, 25 );
}
}

public static void main( String[] args )
{
JFrame f = new JFrame( "Neoplastizismus" );
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
f.setSize( 300, 300 );
f.add( new ColorBox() );
f.setVisible( true );
}
}

Abbildung

Abbildung 10.16: Programmierter Neoplastizismus

Das Fenster der Applikation hat eine gewisse Größe, die wir mit size() in der Höhe und Breite abfragen. Anschließend erzeugen wir Blöcke, die mit einer zufälligen Farbe gefüllt sind. fillRect() übernimmt diese Aufgabe. Da die gefüllten Rechtecke immer in der Vordergrundfarbe gezeichnet werden, setzen wir den Zeichenstift durch die Methode setColor(), die natürlich eine Objektmethode von Graphics ist. Entsprechend gibt es eine korrespondierende Methode getColor(), die die aktuelle Vordergrundfarbe als Color-Objekt zurückgibt (diese Methode darf nicht mit den beiden Methoden aus der Color-Klasse getColor(String) beziehungsweise getColor(String, Color) verwechselt werden).

abstract class java.awt.Graphics
  • abstract void setColor(Color c)
    Setzt die aktuelle Farbe, die dann von den Zeichenmethoden berücksichtigt wird.
  • abstract Color getColor()
    Liefert die aktuelle Farbe.

Vordefinierte Farben

Wenn wir Farben benutzen wollen, sind schon viele Werte vordefiniert, wie Color.WHITE. In der Klasse jawa.awt.Color sind dazu viele Zeilen der Form

/**
* The color white.
*/
public static final Color WHITE = new Color( 255, 255, 255 );

platziert.

Die folgende Tabelle zeigt die deklarierten Konstanten inklusive Wertebelegung für die Farbtupel:

Tabelle 10.1: Farbanteile für die vordefinierten Standardfarben

Color-Konstante Rot Grün Blau

WHITE

255

255

255

BLACK

0

0

0

RED

255

0

0

GREEN

0

255

0

BLUE

0

0

255

YELLOW

255

255

0

MAGENTA

255

0

255

CYAN

0

255

255

PINK

255

175

175

ORANGE

255

200

0

LIGHT_GRAY

192

192

192

DARK_GRAY

64

64

64

Alle Farbnamen gibt es auch kleingeschrieben. Zwar stammt von Sun die Namenskonvention, dass Konstanten großgeschrieben werden, aber bei den Farbnamen wurde das erst in Java 1.4 nachgeholt – sieben Jahre später.

Farbanteile zurückgeben

Mitunter müssen wir den umgekehrten Weg gehen und von einem gegebenen Color-Objekt wieder die Rot-, Grün- oder Blau-Anteile extrahieren. Dies ist einfach, und die Java-Bibliothek bietet Entsprechendes an:

class java.awt.Color
implements Paint, Serializable
  • int getRed()
  • int getGreen()
  • int getBlue()
    Liefert Rot-, Grün- und Blau-Anteile des Farbobjekts im Bereich von 0 bis 255.
  • int getAlpha()
    Gibt den Alpha-Anteil zurück.
  • int getRGB()
    Gibt die RGB-Farbe zurück. Die Bits 24–31 repräsentieren den Alpha-Wert, 16–23 stehen für Rot, 8–15 für Grün und 0–7 für Blau.

Einen helleren oder dunkleren Farbton wählen *

Zwei besondere Methoden sind brighter() und darker(). Sie liefern ein Farbobjekt zurück, das jeweils eine Farbnuance heller beziehungsweise dunkler ist. Die Graphics-Methode draw3DRect() nutzt zum Beispiel diese beiden Methoden, um die Ränder in hellerem oder dunklerem Farbton zu zeichnen.

class java.awt.Color
implements Paint, Serializable
  • Color brighter()
    Gibt einen helleren Farbton zurück.
  • Color darker()
    Gibt einen dunkleren Farbton zurück.

Farbveränderung mit Nullanteilen *

Bei den Farbwerten müssen wir nun die Zusammensetzung aus Rot, Grün und Blau bedenken. Ein voller Wert ist mit 255 belegt. Die Berechnung kann diesen Wert noch modifizieren. Doch ist ein Eintrag mit 0 belegt, so erkennen wir aus der Berechnung, dass der Wert bei null bleiben wird. Daher sollten wir bedenken, was bei reinen Farben (wie etwa Rot) durch ein brighter() passiert. Ein reiner Rotton kann sich zwar in der Helligkeit ändern, aber ein Color.RED.brighter() liefert immer noch Color.RED.

System.out.println( Color.RED.brighter() ); // java.awt.Color[r=255,g=0,b=0]
System.out.println( Color.RED.darker() ); // java.awt.Color[r=178,g=0,b=0]

Bei brighter() kommen die Farben demnach nicht näher an Weiß heran, und bei darker() nicht näher an Schwarz.

Um also echte Helligkeitsveränderungen zu bekommen, müssen wir die Farben vorher umrechnen. Hierzu bieten sich andere Farbräume an, wie beispielsweise der HSB-Raum, in dem wir Komponenten für die Helligkeit haben. RGBtoHSB() gibt ein Feld mit den Werten für Hue, Saturation und Brightness für ein Tripel von Rot-, Grün- und Blau-Werten zurück. Nach einer Veränderung der Helligkeit können wir diesen Farbraum wieder mit HSBtoRGB() zurückkonvertieren.

Die Farbmodelle HSB und RGB *

Zwei Farbmodelle sind in der Computergrafik geläufig: das RGB-Modell, bei dem die Farben durch einen Rot-, Grün- und Blau-Anteil definiert werden, und das HSB-Modell, das die Farben durch Farbton (engl. hue), Farbsättigung (engl. saturation) und Helligkeit (engl. brightness) definiert. Die Farbmodelle können die gleichen Farben beschreiben und ineinander umgerechnet werden.

class java.awt.Color
implements Paint, Serializable
  • static int HSBtoRGB(float hue, float saturation, float brightness)
    Aus einem HSB-kodierten Farbwert wird ein RBG-Farbwert.
  • static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals)
    Verlangt ein Array hsbvals zur Aufnahme von HSB, in dem die Werte gespeichert werden sollen. Das Array kann null sein und wird somit angelegt. Das Feld wird zurückgegeben.
  • static Color getHSBColor(float h, float s, float b)
    Erzeugt ein Color-Objekt mit Werten aus dem HSB-Modell. Implementiert als return new Color(HSBtoRGB(h, s, b)).

Galileo Computing - Zum Seitenanfang

10.5.3 Die Farben des Systems über SystemColor *Zur nächsten ÜberschriftZur vorigen Überschrift

Bei eigenen Java-Programmen ist es wichtig, dass diese sich so perfekt wie möglich in die Reihe der anderen Host-Programme einordnen, ohne großartig aufzufallen. Dafür muss ein Fenster die globalen Einstellungen wie den Zeichensatz und die Farben kennen. Für die Systemfarben gibt es die Klasse SystemColor, die alle Farben einer grafischen Oberfläche auf symbolische Konstanten abbildet. Besonders praktisch ist dies bei Änderungen von Farben während der Laufzeit. Über diese Klasse können immer die aktuellen Werte eingeholt werden, denn ändert sich beispielsweise die Hintergrundfarbe der Laufleisten, ändert sich damit auch der RGB-Wert. Die Systemfarben sind Konstanten von SystemColor und werden mit der Methode getRGB() in eine Ganzzahl umgewandelt.

Die Klasse deklariert die folgenden statischen finalen Variablen:[81](Sun verstößt mal wieder gegen die eigenen Namenskonventionen. Die finalen Variablen – Konstanten – sollten großgeschrieben werden. Das funktioniert bei den SystemColor-Objekten aber nicht, da es alle Bezeichnernamen schon in Großbuchstaben gibt, und zwar für Variablen vom Typ Byte, die Verweise in eine interne Tabelle darstellen.)

class java.awt.SystemColor
implements Serializable

Tabelle 10.2: Konstanten der Systemfarben

SystemColor Welche Farbe darauf anspricht

desktop

Farbe des Desktop-Hintergrunds

activeCaption

Hintergrundfarben für Text im Fensterrahmen

activeCaptionText

Farbe für Text im Fensterrahmen

activeCaptionBorder

Rahmenfarbe für Text im Fensterrahmen

inactiveCaption

Hintergrundfarbe für inaktiven Text im Fensterrahmen

inactiveCaptionText

Farbe für inaktiven Text im Fensterrahmen

inactiveCaptionBorder

Rahmenfarbe für inaktiven Text im Fensterrahmen

window

Hintergrundfarbe der Fenster

windowBorder

Rahmenfarbe der Fenster

windowText

Textfarbe für Fenster

menu

Hintergrundfarbe für Menüs

menuText

Textfarbe für Menüs

text

Hintergrundfarbe für Textkomponenten

textText

Textfarbe für Textkomponenten

textHighlight

Hintergrundfarbe für hervorgehobenen Text

textHighlightText

Farbe des Texts, wenn dieser hervorgehoben ist

textInactiveText

Farbe für inaktiven Text

control

Hintergrundfarbe für Kontrollobjekte

controlText

Textfarbe für Kontrollobjekte

controlHighlight

normale Farbe, mit der Kontrollobjekte hervorgehoben werden

controlLtHighlight

hellere Farbe, mit der Kontrollobjekte hervorgehoben werden

controlShadow

normale Hintergrundfarbe für Kontrollobjekte

controlDkShadow

dunklerer Schatten für Kontrollobjekte

scrollbar

Hintergrundfarbe der Schieberegler

info

Hintergrundfarbe der Hilfe

infoText

Textfarbe der Hilfe

Um die Systemfarbe in eine brauchbare Variable zu konvertieren, gibt es die getRGB()-Methoden. So erzeugt new Color(SystemColor.window.getRGB()) ein Color-Objekt in der Farbe des Fensters.

final class java.awt.SystemColor
implements Serializable
  • int getRGB()
    Liefert den RGB-Wert der Systemfarbe als Ganzzahl kodiert.

Um zu sehen, welche Farben auf dem laufenden System aktiv sind, formulieren wir ein Programm, das eine kleine Textzeile in der jeweiligen Farbe angibt. Da wir auf die internen Daten nicht zugreifen können, müssen wir ein Farbfeld mit SystemColor-Objekten aufbauen.

Abbildung

Abbildung 10.17: Die Systemfarben unter einer Windows-Konfiguration

Listing 10.12: com/tutego/insel/ui/graphics/SystemColors.java

package com.tutego.insel.ui.graphics;

import java.awt.*;
import javax.swing.*;

class SystemColors extends JPanel
{
private String[] systemColorString = {
"desktop", "activeCaption", "activeCaptionText",
"activeCaptionBorder", "inactiveCaption",
"inactiveCaptionText", "inactiveCaptionBorder",
"window", "windowText", "menu", "menuText",
"text", "textText", "textHighlight",
"textHighlightText","textInactiveText",
"control", "controlText", "controlHighlight",
"controlLtHighlight", "controlShadow",
"controlDkShadow", "scrollbar",
"info", "infoText"
};
private SystemColor[] systemColor = {
SystemColor.desktop,
SystemColor.activeCaption,
SystemColor.activeCaptionText,
SystemColor.activeCaptionBorder,
SystemColor.inactiveCaption,
SystemColor.inactiveCaptionText,
SystemColor.inactiveCaptionBorder,
SystemColor.window,
SystemColor.windowText,
SystemColor.menu,
SystemColor.menuText,
SystemColor.text,
SystemColor.textText,
SystemColor.textHighlight,
SystemColor.textHighlightText,
SystemColor.textInactiveText,
SystemColor.control,
SystemColor.controlText,
SystemColor.controlHighlight,
SystemColor.controlLtHighlight,
SystemColor.controlShadow,
SystemColor.controlDkShadow,
SystemColor.scrollbar,
SystemColor.info,
SystemColor.infoText
};

@Override
protected void paintComponent( Graphics g )
{
super.paintComponent( g );
g.setFont( new Font( "Dialog", Font.BOLD, 12 ) );
for ( int i = 0; i < systemColorString.length; i++ ) {
g.setColor( new Color( systemColor[i].getRGB() ) );
g.drawString( systemColorString[i], 20, 60 + (i*13) );
}
}

public static void main( String[] args )
{
JFrame f = new JFrame();
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
f.setSize ( 170, 400 );
f.add( new SystemColors() );
f.setVisible( true );
}
}

Galileo Computing - Zum Seitenanfang

10.5.4 Composite und Xor *Zur nächsten ÜberschriftZur vorigen Überschrift

Ein Composite ist eine Zusammenfügung der zu zeichnenden Elemente und des Hintergrunds. Auf dem Graphics2D-Objekt setzt setComposite(Composite) den Modus, wobei bisher AlphaComposite die einzige direkte Implementierung der Schnittstelle Composite ist. Ein AlphaComposite-Objekt bestimmt, wie die Überblendung aussehen soll.

Beispiel

Zeichne ein Bild image mit dem Alpha-Wert alpha:

Graphics2D g2 = (Graphics2D) g;
g2.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha) );
g2.drawImage( image, 0, 0, this );

Der Xor-Modus

Die zweite Einstellung, wie Farben auf das Ziel wirken, bestimmt der Xor-Modus, der ein spezieller Composite ist, mit dem Pixel, die zweimal gezeichnet werden, ihre Ursprungsfarbe wieder annehmen.

abstract class java.awt.Graphics
  • abstract void setComposite(Composite comp)
    Setzt das Composite-Objekt, das die Verschmelzung der folgenden Zeichenoperationen mit dem Hintergrund definiert.
  • abstract void setXORMode(Color c)
    Setzt die Pixel-Operation auf Xor.

Galileo Computing - Zum Seitenanfang

10.5.5 Dicke und Art der Linien von Formen bestimmen über Stroke *Zur nächsten ÜberschriftZur vorigen Überschrift

Eine noch fehlende Eigenschaft ist die der Umrisslinie, Stroke genannt. Zu den Eigenschaften einer Umrisslinie zählen:

  • die Dicke (engl. width)
  • die Art, wie Liniensegmente beginnen und enden (engl. end caps)
  • die Art, wie aufeinandertreffende Linien verbunden werden (engl. line joins)
  • ein Linien-Pattern (engl. dash attributes)

Die Stroke-Schnittstelle

Die Umrisseigenschaften bestimmen Objekte vom Typ java.awt.Stroke; die Methode setStroke(Stroke) auf dem Graphics2D-Kontext setzt sie. Alle nachfolgenden Methoden wie draw(), drawLine() usw. berücksichtigen diese Umrisslinie anschließend.

Die Schnittstelle Stroke schreibt nur eine Operation vor:

interface java.awt.Stroke
  • Shape createStrokedShape(Shape p)
    Liefert die Umrandung für ein Shape p.

Bisher gibt es in Java nur eine Standardimplementierung der Schnittstelle: BasicStroke.

Beispiel

Zeichne die folgenden Formen mit einer Dicke von zehn Pixeln:

g2.setStroke( new BasicStroke( 10 ) );

Abbildung

Abbildung 10.18: Vererbungsbeziehung von BasicStroke und Stroke

Linienenden (end caps)

Besonders bei breiten Linien ist es interessant, wie eine allein stehende Linie endet. Sie kann einfach aufhören oder auch abgerundet sein. Drei Konstanten bestimmen diesen Linienende-Typ:

  • BasicStroke.CAP_BUTT. Belässt das Ende so, wie es ist.
  • BasicStroke.CAP_ROUND. Rundet das Ende mit einem Halbkreis ab.
  • BasicStroke.CAP_SQUARE. Setzt einen rechteckigen Bereich an.

Die Typen CAP_ROUND und CAP_SQUARE erweitern die Linie um ein Stück, das halb so groß wie die Dicke der Linie ist:

Listing 10.13: com/tutego/insel/ui/g2d/EndCapsDemo.java, paintComponent()

@Override
protected void paintComponent( Graphics g )
{
Graphics2D g2 = (Graphics2D) g;

g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

g2.setStroke( new BasicStroke( 20, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER ) );
g2.drawLine( 30, 50, 200, 50 );

g2.setStroke( new BasicStroke( 20, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER ) );
g2.drawLine( 30, 150, 200, 150 );

g2.setStroke( new BasicStroke( 20, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER ) );
g2.drawLine( 30, 100, 200, 100 );
}

Zwar gibt es von BasicStroke fünf Konstruktoren, aber nur einen einfachen, der Linienenden (immer unterschiedlich in dem Beispiel) und Linienverbindungen (hier BasicStroke.JOIN_MITER) gleichzeitig bestimmt haben möchte.

Abbildung

Abbildung 10.19: Unterschiedliche Linienenden

Linienverbindungen (line joins)

Wenn Linien nicht allein stehen, sondern etwa wie in einem Dreieck oder Rechteck verbunden sind, stellt sich die Frage, wie diese Verbindungspunkte gezeichnet werden. Das bestimmen ebenfalls drei Konstanten:

  • BasicStroke.JOIN_ROUND: Rundet die Ecken ab.
  • BasicStroke.JOIN_BEVEL: Zieht eine Linie zwischen den beiden äußeren Endpunkten.
  • BasicStroke.JOIN_MITER: Erweitert die äußeren Linien so weit, bis sie sich treffen.

Listing 10.14: com/tutego/insel/ui/g2d/LineJoinsDemo.java, paintComponent()

@Override
protected void paintComponent( Graphics g )
{
Graphics2D g2 = (Graphics2D) g;

g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

BasicStroke stroke = new BasicStroke( 20, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL );
g2.setStroke( stroke );

Path2D shape = new GeneralPath();
shape.moveTo( 25, 25 );
shape.lineTo( 50, 100 );
shape.lineTo( 75, 25 );
g2.draw( shape );

//

stroke = new BasicStroke( 20, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER );
g2.setStroke( stroke );

shape = new GeneralPath();
shape.moveTo( 25+100, 25 );
shape.lineTo( 50+100, 100 );
shape.lineTo( 75+100, 25 );
g2.draw( shape );

//

stroke = new BasicStroke( 20, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND );
g2.setStroke( stroke );

shape = new GeneralPath();
shape.moveTo( 25+200, 25 );
shape.lineTo( 50+200, 100 );
shape.lineTo( 75+200, 25 );
g2.draw( shape );
}

Abbildung

Abbildung 10.20: Unterschiedliche Linienverbindungen BEVEL, MITER, ROUND

Falls der Typ der Linienverbindungen JOIN_MITER ist, kann mit einem spitzen Winkel die Verbreiterung sehr lang werden. Die Variable miterlimit beim Konstruktor kann die maximale Länge beschränken, sodass über einer gewissen Größe die beiden Linien mit JOIN_BEVEL enden.

Füllmuster (dash)

Auch die Muster, mit denen die Linien oder Kurven gezeichnet werden, lassen sich ändern. Dazu erzeugen wir vorher ein float-Feld und übergeben es einem Konstruktor.

Abbildung

Abbildung 10.21: Kodierung der Füllmuster

Die folgenden Zeilen erzeugen ein Rechteck mit einem einfachen Linienmuster. Es sollen zehn Punkte gesetzt und zwei Punkte frei sein. Damit auch die Muster abgerundet werden, muss CAP_ROUND gesetzt sein:

Listing 10.15: com/tutego/insel/ui/g2d/DashDemo.java, Ausschnitt

float[] dash = { 10, 2 };
BasicStroke stroke = new BasicStroke( 2,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
1,
dash, 0 );

g2.setStroke( stroke );
g2.draw( new Rectangle2D.Float( 50, 50, 50, 50 ) );

Als letztes Argument hängt am Konstruktor von BasicStroke noch eine Verschiebung. Dieser Parameter bestimmt, wie viele Pixel im Muster übersprungen werden sollen. Geben wir dort für unser Beispiel etwa 10 an, so beginnt die Linie gleich mit zwei nicht gesetzten Pixeln. Eine 12 ergibt eine Verschiebung wieder an den Anfang. Bei nur einer Zahl im Feld sind der Abstand der Linien und die Breite einer Linie genauso lang, wie diese Zahl angibt. Bei gepunkteten Linien ist das Feld also 1. Hier eignet sich ein anonymes Feld ganz gut, wie die nächsten Zeilen zeigen:

stroke = new BasicStroke( 1,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL,
1, new float[]{ 1 }, 0 );

Bei feinen Linien sollten wir das Weichzeichnen besser ausschalten.

Abbildung

Abbildung 10.22: Zwei Linienmuster



Ihr Kommentar

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







<< zurück
  Zum Katalog
Zum Katalog: Java 7 – Mehr als eine Insel
Java 7 – Mehr als eine Insel
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java und XML






 Java und XML


Zum Katalog: Einstieg in Eclipse 3.7






 Einstieg in
 Eclipse 3.7


Zum Katalog: Android 3






 Android 3


Zum Katalog: NetBeans Platform 7






 NetBeans Platform 7


Zum Katalog: Java ist auch eine Insel






 Java ist
 auch eine Insel


Zum Katalog: Apps entwickeln für Android 4






 Apps entwickeln
 für Android 4


Zum Katalog: Java 7






 Java 7


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das 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