Advanced   Java   Services
pluggable look and feel
Back Next Up Home

basics


AWT-Komponenten werden betriebssystemabhängig dargestellt. Ein AWT-Button schaut unter Motif aus wie ein Motif-Button eben aussieht und analog für andere Betriebssysteme. Man kann die Vorder- und Hintergrundfarbe verändern, eine andere Schrift wählen und die Größe verändern und das war es im wesentlichen. AWT-Komponenten überlassen ihre Darstellung hauptsächlich dem darunterliegenden Betriebssystem. Daher kann man den AWT-Komponenten kein eigenständiges LAF (look and feel) geben, es sei denn, man strickt es sich selbst, indem man von Component ableitet. Aber diese Arbeit kann man sich sparen, das ist ja schon passiert und heißt dann Swing...

Swingkomponenten delegieren ihre Darstellung nicht ans Betriebssystem, sondern zeichnen sich selbst. Dazu gibt es zu jeder von JComponent abgeleiteten Klasse JXxx eine Klasse XxxUI, die für die Darstellung der jeweiligen JComponente verantwortlich ist (zu JButton ein ButtonUI, zu JList ein ListUI etc.). U.a. werden also etwa paint()-Aufrufe von JXxx an XxxUI weitergeleitet. Lediglich die ToplevelContainer JFrame, JWindow, JDialog und JApplet, die sich nicht von JComponent ableiten delegieren ihre Darstellung nach wie vor ans OS. Auf Grund dieses Verhaltens nennt man JComponent und alle davon abgeleiteten Klassen lightweight-Komponenten.

LookAndFeel


Das typische Erscheinungsbild einer bestimmten graphischen Oberfläche korrespondiert jeweils mit einer Klasse vom Typ LookAndFeel, genauer gesagt mit einer Klasse, die sich immer von der abstrakten Klasse LookAndFeel ableitet. In der Praxis leitet sich die entsprechende LAFklasse meist von BasicLookAndFeel ab, da diese Klasse Standardarbeiten erledigt, die eigentlich für alle LAFs notwendig sind. Die folgende Graphik zeigt die vier gängigsten LookAndFeelklassen.


Die folgende Tabelle bringt eine Übersicht über einige wichtige Methoden der Klasse LookAndFeel

public abstract class LookAndFeel



Konstruktor
LookAndFeel() 
Methoden
ReturntypName der Methode
UIDefaults
 
getDefaults()
This method is called once by UIManager.setLookAndFeel to create the look and feel specific defaults table.
abstract String
 
getID()
Return a string that identifies this look and feel.
abstract String
 
getName()
Return a short string that identifies this look and feel, e.g. "CDE/Motif".
boolean
 
getSupportsWindowDecorations()
Returns true if the LookAndFeel returned RootPaneUI instances support providing Window decorations in a JRootPane. New in 1.4
void
 
initialize()
UIManager.setLookAndFeel calls this method before the first call (and typically the only call) to getDefaults().
abstract boolean
 
isNativeLookAndFeel()
If the underlying platform has a "native" look and feel, and this is an implementation of it, return true.
abstract boolean
 
isSupportedLookAndFeel()
Return true if the underlying platform supports and or permits this look and feel. Es geht nur um "permits"...
void
 
uninitialize()
UIManager.setLookAndFeel calls this method just before we're replaced by a new default look and feel.

UIDefaults


Die wichtigste Methode aus der Klasse LookAndFeel ist getDefaults(). Sie liefert ein Objekt vom Typ UIDefaults. UIDefaults ist eine spezialisierte Hashtable, also eine key/value-Tabelle. In dieser Tabelle ist für jede JComponente ihr zu diesem LookAndFeel gehörendes outfit gespeichert. Hier einige Beispiele von key/value Einträgen in UIDefaults für MetalLookAndFeel.

key value
Button.backgroundjavax.swing.plaf.ColorUIResource[r=204,g=204,b=204]
Button.fontjavax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12]
Button.textIconGap4
......
ButtonUIjavax.swing.plaf.metal.MetalButtonUI
List.focusCellHighlightBorderjavax.swing.plaf.BorderUIResource$LineBorderUIResource
List.selectionBackgroundjavax.swing.plaf.ColorUIResource[r=204,g=204,b=255]
Button.textIconGap4
......
ListUIjavax.swing.plaf.metal.BasicListUI
......

Hauptsächlich werden in diesen Tabelle Farben, Fonts und Borders hinterlegt. Die Tabellen sind recht umfangreich, für die vier oben erwähnten LAFs ergeben sich jeweils ca. 550 key/value Paare. Eine komplette Liste für die vier StandardLookAndFeels findet man unter UIDefaultWerte. getDefaults() aus LookAndFeel liefert nicht nur diese Tabelle, sondern erzeugt sie auch.

UIManager


Wie erfährt nun eine Applikation, welches LAF für sie zuständig ist? Dafür gibt es den UIManager. Beim Start einer Applikation und bevor das GUI mit setVisible(true) sichtbar wird, wird dieser automatisch aktiv. Standardmäßig erzeugt er ein Objekt vom Typ MetalLookAndFeel, ruft zu diesem Objekt getDefaults und hält so einen Zeiger auf die zugehörige UIDefaultstabelle. Alle von JComponent abgeleitete Komponenten holen sich die Information zu ihrer Darstellung mit Hilfe der Klasse UIManager.

Die Klasse UIManager ist der Ausgangspunkt um sich Informationen über Look And Feels zu holen und gegebenenfalls Look And Feels zu installieren oder zu setzen. Wie man aus der API ersehen kann, ist UIManager eine Klasse, die nur statische Methoden besitzt. Sie ist also eine typische Hilfsklasse, von der man keine Instanzen anlegt. Hier einige Methoden dieser Klasse.

Einige Methoden
ReturntypName der Methode
static String
 
 
getCrossPlatformLookAndFeelClassName()
Returns the name of the LookAndFeel class that implements the default cross platform look and feel -- the Java Look and Feel (JLF).
static UIDefaults
 
getDefaults()
Returns the default values for this look and feel.
static UIManager.LookAndFeelInfo[]
 
getInstalledLookAndFeels()
Returns an array of objects that provide some information about the LookAndFeel implementations that have been installed with this software development kit.
static LookAndFeel
 
getLookAndFeel()
Returns the current default look and feel or null.
static UIDefaults
 
getLookAndFeelDefaults()
Returns the default values for this look and feel.
static String
 
getSystemLookAndFeelClassName()
Returns the name of the LookAndFeel class that implements the native systems look and feel if there is one, otherwise the name of the default cross platform LookAndFeel class.
static ComponentUI
 
getUI(JComponent target)
Returns the L&F object that renders the target component.
static void
 
installLookAndFeel(String name, String className)
Creates a new look and feel and adds it to the current array.
static void
 
installLookAndFeel(UIManager.LookAndFeelInfo info)
Adds the specified look and feel to the current array and then calls setInstalledLookAndFeels(javax.swing.UIManager.LookAndFeelInfo[]).
static void
 
setInstalledLookAndFeels(UIManager.LookAndFeelInfo[] infos)
Replaces the current array of installed LookAndFeelInfos.
static void
 
setLookAndFeel(LookAndFeel newLookAndFeel)
Sets the current default look and feel using a LookAndFeel object.
static void
 
setLookAndFeel(String className)
Sets the current default look and feel using a class name.


Zusätzliche LookAndFeels


MetalLookAndFeel und MotifLookAndFeel werden mit jedem JDK ausgeliefert, MacLookAndFeel und WindowsLookAndFeel aus rechtlichen Gründen nur auf den jeweiligen Betriebssystemen. Wer MacLookAndFeel zu privaten Zwecken ausprobieren will, kann es sich mit dem folgenden Link herunterladen. Wer verschiedene LAFs ausprobieren will, findet bei "javatoo" ein schöne Auswahl.


UIManager.LookAndFeelInfo


Der UIManager unterscheidet zwischen einem gesetzen LookAndFeel und installierten LookAndFeels. Zu dem einen gesetzten LAF existiert die Tabelle der UIDefaults, die verwendet wird, um das Aussehen der Komponenten zu bestimmen. Daneben gibt es eine (meist kleine) Liste von installierten LAFs. Über diese Liste erfährt man, welche anderen LAFs der UIManager noch kennt. Aus dieser Liste kann man dann ein anderes LAF auswählen und es setzen. In disem Fall holt sich der UIManager eine neue UIDefaultsTabelle von dem neuen LookAndFeelObjekt. Die installierten LAFs werden in einem Array verwaltet. Die Elemente dieses Arrays sind vom Typ der statischen nested class UIManager.LookAndFeelInfo. Wie man aus dem Quellcode erkennt, kapselt die Klasse lediglich zwei Strings.

public static class LookAndFeelInfo
{
   private String name;
   private String className;

   public LookAndFeelInfo(String name, String className)
   {
      this.name = name;
      this.className = className;
   }

   public String getName()
   {
      return name;
   }

   public String getClassName()
   {
      return className;
   }
   //...

}

Ein zusätzliches LookAndFeel installieren

Ein zusätzliches LAF wird am einfachsten mit der Methode

installiert. Das folgende Beispiel installiert zwei neue LAFs.

UIManager.installLookAndFeel("mac","com.sun.java.swing.plaf.mac.MacLookAndFeel") ;
UIManager.installLookAndFeel("kunststoff", "com.incors.plaf.kunststoff.KunststoffLookAndFeel" );

Entscheidend ist der zweite String. Will man das LAF später auch setzen, so muß er den kompletten Packagenamen zur Klasse XxxLookAndFeel enthalten. Dieses package legt man als JavaArchiv (xxx.jar) in das Verzeichnis %JAVA_HOME%/jre/lib/ext. Sie auch das Kapitel über packages unter Grundlagen2.

top Back Next Up Home