![]() |
|
|
14.8.3 Vordefinierte Farben
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Farbname | 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 in klein; sie waren auch die ersten. Zwar stammt von Sun die Namenskonvention, dass Konstanten großgeschrieben werden, aber bei den Farbnamen wurde das erst in Java 1.4 nachgeholt – 7 Jahren später.
Um eine Farbbeschreibung im hexadezimalen Format in einzelne Farbkomponenten der Color-Klasse zu zerlegen, also zum Beispiel von FFFFFF nach (255,255,255), gibt es zwei einfache und elegante Wege. Der erste führt über die Wrapper-Klasse Integer. Die folgende Zeile erzeugt aus dem String colorHexString ein Color-Objekt:
Color color = new Color( Integer.parseInt(colorHexString, 16) );
Ein anderer Weg ist noch eleganter, da die Color-Klasse eine einfache Routine bereitstellt:
Color color = Color.decode( "#" + colorHexString );
decode(String) verlangt eine 24-Bit-Integer-Zahl als String kodiert. Durch das Hash-Symbol und das Plus erzeugen wir ein String-Objekt, welches als Hexadezimalzahl bewertet wird.
class java.awt. Color implements Paint, Serializable |
| Color decode( String nm ) throws NumberFormatException Liefert die Farbe vom übergebenen String. Die Zeichenkette ist als 24-Bit-Integer kodiert. |
Nun wertet decode() den String aus, indem wiederum die decode()-Funktion der Integer-Klasse aufgerufen wird. Aus diesem Rückgabewert wird dann wiederum das Color-Objekt aufgebaut.
public static Color decode( String nm ) throws NumberFormatException { Integer intval = Integer.decode( nm ); int i = intval.intValue(); return new Color( (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF ); }
Wir sehen, dass bei falschen Werten eine NumberFormatException ausgelöst wird. Diese Exception kommt von der decode()-Funktion der Integer-Klasse. Die Implementierung verrät uns die Arbeitsweise und zeigt uns auf, dass wir auch aus Oktalziffern ein Color-Objekt erzeugen könnten oder aber aus einem String, der nicht mit dem Hash-Zeichen, sondern mit dem gewohnten Präfix 0x beginnt.
public static Integer decode( String nm ) throws NumberFormatException { if ( nm.startsWith("0x") ) { return Integer.valueOf(nm.substring(2), 16); } if ( nm.startsWith("#") ) { return Integer.valueOf(nm.substring(1), 16); } if ( nm.startsWith("0") && nm.length() > 1 ) { return Integer.valueOf( nm.substring(1), 8 ); } return Integer.valueOf( nm ); }
Zwei besondere Funktionen sind brighter() und darker(). Sie liefern ein Farb-Objekt zurück, das jeweils eine Farbnuance heller beziehungsweise dunkler ist.
Beispiel Die Implementierung von draw3DRect() zeigt den Einsatz der Funktionen.
public void draw3DRect(int x, int y, int width, int height, boolean raised) { Color c = getColor(); Color brighter = c.brighter(); Color darker = c.darker(); setColor(raised ? brighter : darker); drawLine(x, y, x, y + height); drawLine(x + 1, y, x + width – 1, y); setColor(raised ? darker : brighter); drawLine(x + 1, y + height, x + width, y + height); drawLine(x + width, y, x + width, y + height – 1); setColor(c); } |
Wie viele andere Funktionen aus der Color-Klasse sind auch die Routinen sichtbar implementiert, also nicht nativ:
public Color brighter() { return new Color(Math.min((int)(getRed() *(1/FACTOR)), 255), Math.min((int)(getGreen()*(1/FACTOR)), 255), Math.min((int)(getBlue() *(1/FACTOR)), 255)); } public Color darker() { return new Color(Math.max((int)(getRed() *FACTOR), 0), Math.max((int)(getGreen()*FACTOR), 0), Math.max((int)(getBlue() *FACTOR), 0)); }
FACTOR ist eine finale Konstante, die durch 0,7 vordefiniert ist. Sie lässt sich also nicht ändern.
class java.awt. Color implements Paint, Serializable |
| Color brighter() Gibt einen helleren Farbton zurück. |
| Color darker() Gibt einen dunkleren Farbton zurück. |
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]
Es ist also nicht so, dass bei brighter() die Farben näher an Weiß herankommen und bei darker() 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.
Zwei Farbmodelle sind in der Computergrafik geläufig. Das RGB-Modell, wo die Farben durch einen Rot-, Grün- und Blau-Anteil definiert werden, oder das HSB-Modell, das die Farben durch Grundton (Hue), Farbsättigung (Saturation) und Helligkeit (Brightness) definiert. Die Farbmodelle können die gleichen Farben beschreiben und 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 gemacht. |
| 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 ) Die Funktion kann genutzt werden, um Color-Objekte aus einem HSB-Modell zu erzeugen. |
Die Implementierung von getHSBColor() ist ein Witz:
public static Color getHSBColor(float h, float s, float b) { return new Color(HSBtoRGB(h, s, b)); }
Bei eigenen Java-Programmen ist es wichtig, dass diese sich so perfekt wie möglich in die Reihe der anderen Host-Programme einreihen, 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, welche 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, so ändert sich damit auch der RGB-Wert. Die Systemfarben sind Konstanten von SystemColor und werden mit der Funktion getRGB() in eine Ganzzahl umgewandelt.
Die Klasse definiert folgende statischen finalen Variablen1 :
class java.awt. SystemColor implements Serializable |
| SystemColor | Welche Farbe 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 Kontroll-Objekte |
| controlText | Textfarbe für Kontroll-Objekte |
| controlHighlight | Normale Farbe, mit der Kontroll-Objekte hervorgehoben werden |
| controlLtHighlight | Hellere Farbe, mit der Kontroll-Objekte hervorgehoben werden |
| controlShadow | Normale Hintergrundfarbe für Kontroll-Objekte |
| controlDkShadow | Dunklerer Schatten für Kontroll-Objekte |
| 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()-Funktion. 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.

Hier klicken, um das Bild zu Vergrößern
Abbildung 14.5 Die Systemfarben unter einer Windows-Konfiguration
Listing 14.14 SystemColors.java
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 }; 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 ); } }
1 Mal wieder verstößt Sun gegen die eigenen Namenskonventionen. Die finalen Variablen – Konstanten – sollten groß geschrieben werden. Das geht für die SystemColor-Objekte aber nicht, da es alle Bezeichnernamen schon in groß gibt, und zwar für Variablen vom Typ Byte, für Verweise in eine interne Tabelle.
| << zurück |
Copyright © Galileo Press GmbH 2004
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.