Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


8.7.4

SwingUtilities



Die SwingUtilities-Klasse bietet neben Konvertierungsfunktionen (beispielsweise zur Konvertierung der Koordinaten eines MouseEvent in die der Zielkomponente) und allerlei nützlichen Informationen (beispielsweise das Fenster zu einer Komponente) auch die Möglichkeit, bestimmte Aktionen in der EventQueue von Swing abzulegen.

Bei Swing ist der gleiche Thread dafür zuständig, die Oberfläche neu zu zeichnen und die Events abzuarbeiten.

Dies wird besonders deutlich, wenn bei einem kurzen Drücken eines Buttons etwas Rechenintensives geschieht. Da der Thread, der dieses Ereignis auslöst der gleiche ist, der für das Zeichnen des Buttons verantwortlich ist, bleibt der Button gedrückt gezeichnet, solange die actionPerformed(ActionEvent e)-Methode des ActionListener nicht verlassen wird. Erst danach wird der Button wieder so gezeichnet, wie man es erwartet, wenn die Maustaste losgelassen wurde.

Möchte man hier eine Aktion erst ausführen, wenn bspw. die Oberfläche komplett neu gezeichnet ist oder alle Events abgearbeitet sind, benutzt man eine der Methoden invokeLater(Runnable r) bzw. invokeAndWait(Runnable r):
  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      // Wird erst aufgerufen, wenn alle 
      // Aufgaben abgearbeitet wurden
    }
  });
Während invokeLater asynchron am Ende aufgerufen wird, wird invokeAndWait synchron aufgerufen. Dies bedeutet, dass bei invokeLater das Programm zunächst weiterläuft, während die Abarbeitung bei invokeAndWait stoppt, bis die run()-Methode verlassen wird. Die invokeAndWait-Methode kann dadurch natürlich nur sinnvoll in einem anderen Thread verwendet werden. Dieser Thread wird dadurch so lange blockiert, bis der Swing-Thread seine Aufgaben erfüllt hat.

Pluggable Look and Feel

Eine weitere wichtige Eigenschaft von Swing ist die Möglichkeit, das Look-and-Feel jederzeit auszutauschen, ohne dass die Applikation neu kompiliert werden muss.

Zu diesem Zweck werden die entsprechenden Look-and-Feel-Klassen in einem Paket zusammengefasst. Jedes Oberflächenelement hat dabei eine entsprechende, von ComponentUI indirekt abgeleitete Klasse. Diese Klasse besteht aus dem spezifischen Namen des Look-and-Feels, dem Namen der Komponente (ohne den Buchstaben J) und dem Appendix UI (z.B. javax.swing.plaf.basic.BasicButtonUI). Diese Klassen erben von den abstrakten Klassen des Packages javax.swing.plaf (z.B. javax.swing.plaf.ButtonUI).

Jedes Look-and-Feel beinhaltet eine Klasse, welche von LookAndFeel abgeleitet ist. Diese Klasse liefert neben allgemeinen Informationen zu dem Look-and-Feel eine Hashtable (UIDefault), mit den komponentenspezifischen Standard-Informationen, wie beispielsweise die Standard-Hintergrundfarbe eines Buttons.

Das Look-and-Feel wird über die Klasse UIManager gesetzt. Dazu dient die Methode setLookAndFeel(...). Um alle Oberflächenkomponenten über diese Änderung zu informieren, kann die Methode SwingUtilities.updateComponentTreeUI(Compoent c) aufgerufen werden.

Will man zum Beispiel das Look-and-Feel ausgehend vom Fenster meinFenster auf Windows umschalten, so geschieht das durch
  UIManager.setLookAndFeel(
    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
  SwingUtilities.updateComponentTreeUI(meinFenster);

Abbildung 8.53: SwingSet-Demo mit Java-, Windows-, Motif- und Mac-OS-X-Look-and-Feel
Abbildung 8.53

Es empfiehlt sich dabei, die vorhandenen Look-and-Feels mit Hilfe der entsprechenden Methoden aus UIManager vorher abzufragen, da unterschiedliche Virtual Machines dort differieren könnten (so ist das Macintosh Look-and-Feel beispielsweise nur auf einem Macintosh-Rechner aufrufbar):

  public static String 
                getCrossPlatformLookAndFeelClassName()  
  public static String 
                getSystemLookAndFeelClassName()
  public static UIManager.LookAndFeelInfo[] 
                getInstalledLookAndFeels()   

Rahmen

Jede von JComponent abgeleitete Klasse kann einen Rahmen (Border) besitzen. Alle Rahmen, die Swing zur Verfügung stellt, sind im Package javax.swing.border zusammengefasst. Um einen Rahmen zu erstellen, sollte man die Klasse BorderFactory benutzen. Diese hat entsprechende create-Methoden, um die im Folgenden beschriebenen Rahmen zu erstellen. Die Factory versucht, schon vorhandene Exemplare wiederzuverwenden, um eine bessere Performance zu erreichen.

Abbildung 8.54: Verschiedene Rahmen, kombiniert jeweils mit einem TitledBorder
Abbildung 8.54

Beispiel:

  JPanel p = new JPanel();
  p.setBorder(
    BorderFactory.createTitledBorder("Benutzerdaten"));


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.