From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+In diesem Abschnitt soll ein einfaches Beispielprogramm vorgestellt
+werden. Es handelt sich um eine einfache (und weitgehend sinnfreie)
+Swing-Anwendung mit einem Hauptfenster, in dem drei Gruppen von Komponenten
+untergebracht sind:
+
+Die beiden Panels wurden mit einer Umrandung versehen, und alle aktiven
+Elemente zeigen Tooltips an, wenn man mit dem Mauszeiger darauf zeigt.
+Durch Drücken auf den Schließen-Button in der Titelleiste
+kann das Programm beendet werden. Die übrigen Dialogelemente
+besitzen - neben ihrem Standardverhalten - keinerlei zusätzliche
+Funktionalität.
+
+
+Abbildung 35.1 zeigt das Beispielprogramm
+mit dem Standard-Look-and-Feel von Java-Programmen (das auch als Metal-Look-and-Feel
+bezeichnet wird):
+
+
+
+Abbildung 35.1: Das Beispielprogramm im Metal-Look-and-Feel
+Oben links ist das Label »Name« mit seinem zugeordeten Icon
+zu erkennen. In das Textfeld wurde bereits der String »Meier,
+Karl-Friedrich« eingetragen. In der Liste ist der Monat Juni
+ausgewählt, und ihre Tooltips werden angezeigt, weil der Mauszeiger
+über der Liste verweilt. Die beiden Panels haben eine zusätzliche
+Umrandung, die vom Programm explizit hinzugefügt wurde.
+
+
+Durch Drücken der Buttons kann das Look-and-Feel umgeschaltet
+werden. Abbildung 35.2 zeigt
+das Programm mit aktiviertem Motif-, Abbildung 35.3
+mit aktiviertem Windows-Look-and-Feel.
+
+
+Während das Metal-Look-and-Feel für Swing neu entwickelt
+wurde, versuchen die beiden anderen, die speziellen Eigenschaften
+der korrespondierenden Fenstersysteme nachzuahmen. In der Praxis gelingt
+ihnen das mit wechselndem Erfolg. Insbesondere Anwender, die sehr
+an eines der beiden Fenstersysteme gewöhnt sind, werden viele
+kleine Abweichungen in der Swing-Implementierung feststellen.
+Zu bedenken ist auch, dass einige der Look-and-Feels aus Lizenzgründen
+nur auf ihren Originalplattformen zur Verfügung stehen (z.B.
+das Windows- und das Mac-Look-and-Feel).
+
+
+Abbildung 35.2: Das Beispielprogramm im Motif-Look-and-Feel
+
+
+Abbildung 35.3: Das Beispielprogramm im Windows-Look-and-Feel
+Zunächst wollen wir uns den Quellcode des Beispielprogramms ansehen.
+Er besteht aus der Klasse für das Hauptfenster, die lediglich
+einen parameterlosen Konstruktor und die Methode actionPerformed
+enthält. Der Programmcode ähnelt den Beispielen, die wir
+zum AWT gesehen haben:
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 35 - Swing: Grundlagen
+
+
+
+
+
+35.2 Ein einführendes Beispiel
+
+
+
+
+
+
+
+35.2.1 Das Beispielprogramm
+
+
+
+
+
+
+
+
+
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Hinweis
+
+
35.2.2 Beschreibung des Beispielprogramms
+
+
+
+
+Listing 35.1: Ein einfaches Swing-Beispielprogramm
+
+
+
+
+
+001 /* Listing3501.java */
+002
+003 import java.awt.event.*;
+004 import java.awt.*;
+005 import javax.swing.*;
+006
+007 public class Listing3501
+008 extends JFrame
+009 implements ActionListener
+010 {
+011 private static final String[] MONTHS = {
+012 "Januar", "Februar", "März", "April",
+013 "Mai", "Juni", "Juli", "August",
+014 "September", "Oktober", "November", "Dezember"
+015 };
+016
+017 public Listing3501()
+018 {
+019 super("Mein erstes Swing-Programm");
+020 //Panel zur Namenseingabe hinzufügen
+021 JPanel namePanel = new JPanel();
+022 JLabel label = new JLabel(
+023 "Name:",
+024 new ImageIcon("triblue.gif"),
+025 SwingConstants.LEFT
+026 );
+027 namePanel.add(label);
+028 JTextField tf = new JTextField(30);
+029 tf.setToolTipText("Geben Sie ihren Namen ein");
+030 namePanel.add(tf);
+031 namePanel.setBorder(BorderFactory.createEtchedBorder());
+032 getContentPane().add(namePanel, BorderLayout.NORTH);
+033 //Monatsliste hinzufügen
+034 JList list = new JList(MONTHS);
+035 list.setToolTipText("Wählen Sie ihren Geburtsmonat aus");
+036 getContentPane().add(new JScrollPane(list), BorderLayout.CENTER);
+037 //Panel mit den Buttons hinzufügen
+038 JPanel buttonPanel = new JPanel();
+039 JButton button1 = new JButton("Metal");
+040 button1.addActionListener(this);
+041 button1.setToolTipText("Metal-Look-and-Feel aktivieren");
+042 buttonPanel.add(button1);
+043 JButton button2 = new JButton("Motif");
+044 button2.addActionListener(this);
+045 button2.setToolTipText("Motif-Look-and-Feel aktivieren");
+046 buttonPanel.add(button2);
+047 JButton button3 = new JButton("Windows");
+048 button3.addActionListener(this);
+049 button3.setToolTipText("Windows-Look-and-Feel aktivieren");
+050 buttonPanel.add(button3);
+051 buttonPanel.setBorder(BorderFactory.createEtchedBorder());
+052 getContentPane().add(buttonPanel, BorderLayout.SOUTH);
+053 //Windows-Listener
+054 addWindowListener(new WindowClosingAdapter(true));
+055 }
+056
+057 public void actionPerformed(ActionEvent event)
+058 {
+059 String cmd = event.getActionCommand();
+060 try {
+061 //PLAF-Klasse auswählen
+062 String plaf = "unknown";
+063 if (cmd.equals("Metal")) {
+064 plaf = "javax.swing.plaf.metal.MetalLookAndFeel";
+065 } else if (cmd.equals("Motif")) {
+066 plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
+067 } else if (cmd.equals("Windows")) {
+068 plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
+069 }
+070 //LAF umschalten
+071 UIManager.setLookAndFeel(plaf);
+072 SwingUtilities.updateComponentTreeUI(this);
+073 } catch (UnsupportedLookAndFeelException e) {
+074 System.err.println(e.toString());
+075 } catch (ClassNotFoundException e) {
+076 System.err.println(e.toString());
+077 } catch (InstantiationException e) {
+078 System.err.println(e.toString());
+079 } catch (IllegalAccessException e) {
+080 System.err.println(e.toString());
+081 }
+082 }
+083
+084 public static void main(String[] args)
+085 {
+086 Listing3501 frame = new Listing3501();
+087 frame.setLocation(100, 100);
+088 frame.pack();
+089 frame.setVisible(true);
+090 }
+091 }
+
+
+Listing3501.java
+
+
![]() |
+
+
+ +In vielen Beispielen in diesem Buch wird der Einfachheit halber die +in Abschnitt 23.2.4 vorgestellte +Klasse WindowClosingAdapter +verwendet, um einen Listener zum Schließen des Fensters zu registrieren. +Damit ein solches Beispiel sich kompilieren läßt, muss +die Datei WindowClosingAdapter.java im +aktuellen Verzeichnis vorhanden sein. Sie befindet sich auf der DVD +zum Buch oder in Listing 23.2. |
+
+
|
+![]() |
+
+Im Gegensatz zu AWT-Programmen besitzt unser Beispielprogramm keine +Anweisung, um das Paket java.awt +zu importieren. Da alle Swing-Komponenten in javax.swing +und seinen Unterpaketen stecken, benötigen wir diese in diesem +Beispiel nicht. Neben den Dialogelementen gibt es allerdings andere +Klassen aus java.awt, +die häufig auch in Swing-Programmen benötigt werden (nur +eben in diesem einfachen Beispiel nicht), etwa die Layoutmanager, +Color- +oder Font-Objekte +oder die Klasse Graphics. + +
+Das Paket java.awt.event +wird dagegen regelmäßig auch in Swing-Programmen benötigt, +denn es enthält die Klassen für das Versenden von Events +und Registrieren von Event-Handlern. Diese werden in Swing-Programmen +in der gleichen Art und Weise benötigt wie in AWT-Programmen. + + + + +
+Das Hauptfenster unserer Anwendung ist aus der Klasse JFrame +abgeleitet, die ihrerseits aus Frame +abgeleitet ist. JFrame +ist eine der vier Klassen, mit denen in Swing Hauptfenster erzeugt +werden können (JDialog, +JWindow +und JApplet +sind die anderen drei). JFrame +hat ähnliche Eigenschaften wie Frame +und wird auch ähnlich programmiert wie diese. Beide unterscheiden +sich jedoch in einem bedeutenden Punkt voneinander. + +
+In Zeile 032 ist zu +sehen, dass eine Komponente nicht einfach mit add +auf dem Fenster platziert wird. Statt dessen wird zunächst eine +Methode getContentPane +aufgerufen, und erst auf dem von ihr zurückgegebenen Container +wird das Dialogelement mit add +platziert. Diese - auf den ersten Blick umständliche - Vorgehensweise +ist allen Swing-Hauptfenstern gemein und wird durch deren innere Struktur +verursacht. Der eigentliche Container mit den sichtbaren Dialogelementen +(die ContentPane) ist nämlich +Bestandteil einer ganzen Reihe geschachtelter Komponenten, in denen +die übrigen Bestandteile des Fensters (etwa dessen Menü) +untergebracht sind. +
+
![]() |
+
+
+ +Neben add +darf auch die Methode setLayout +nicht mehr direkt auf dem Hauptfenster aufgerufen werden. Analog zu +add +ist statt dessen getContentPane().setLayout() +aufzurufen. Ein Verstoß gegen diese Regel löst in beiden +Fällen eine Exception aus. |
+
+
|
+![]() |
+
+Die Buttonleiste und das Label mit seinem Textfeld werden im Beispielprogramm +auf einem JPanel +platziert. JPanel +ist das Swing-Pendant zu Panel +und dient wie dieses dazu, eine Reihe von Dialogelementen unter Kontrolle +eines eigenen Layoutmanagers anzuordnen. Anders als bei den Hauptfenstern +gibt es hier keine ContentPane, sondern die Dialogelemente +und der Layoutmanager werden dem Panel direkt zugewiesen. Die Bedienung +eines JPanel +entspricht fast vollständig der eines Panel. +
+
![]() |
+
+
+ +Die Vaterklasse von JPanel +ist JComponent. +Sie wird - mit Ausnahme der Hauptfenster - als Basisklasse für +praktisch alle Swing-Komponenten verwendet. JComponent +ist direkt aus Container +abgeleitet und besitzt daher alle Eigenschaften der Klassen Component +und Container. +Die technische Unterscheidung zwischen Dialogelementen mit bzw. ohne +Unterelemente wurde damit in Swing fallengelassen. Dennoch ist ein +Button im praktischen Sinne natürlich nach wie vor ein elementares +Dialogelement, und es gibt keine sinnvolle Möglichkeit, weitere +Dialogelemente darauf zu platzieren. |
+
+
|
+![]() |
+
+Ein JLabel +ist ein Dialogelement zur Anzeige eines (meist unveränderlichen) +Textes. Es wird im Beispielprogramm verwendet, um das Textfeld im +oberen Teil des Fensters zu beschriften. Im Gegensatz zu einem Label +kann ein JLabel +zusätzlich ein Icon enthalten. Im Beispielprogramm wird es in +Zeile 024 direkt an +den Konstruktor der Klasse übergeben. Auf diese Weise ist es +sehr einfach möglich, zusätzliche grafische Elemente in +Swing-Dialogen zu platzieren. + + + + +
+Ein JTextField +repräsentiert ein einzeiliges Eingabefeld für Textdaten. +Für einfache Anwendungsfälle entspricht seine Bedienung +der Klasse TextField. +Unser Beispiel verwendet es zur Eingabe eines Namens. Zur verdeckten +Eingabe von Paßwörtern eignet sich die aus JTextField +abgeleitete Klasse JPasswordField. +Sie entspricht einem TextField +nach Aufruf von setEchoCharacter. + + + + +
+Einige der Dialogelemente im Beispielprogramm enthalten einen Tooltip-Text. +Dieser wird angezeigt, wenn die Maus über das Dialogelement bewegt +und dort gehalten wird. Ein Tooltip sollte zusätzliche Informationen +geben, die dem unerfahrenen Anwender eine Hilfe bei der Bedienung +des Programms sind. Tooltips werden mit der Methode setToolTipText +definiert, die alle aus JComponent +abgeleiteten Komponenten besitzen. + +
+Eine andere Fähigkeit, die ebenfalls bereits in der Klasse JComponent +realisiert wurde, besteht darin, beliebigen Komponenten eine Umrandung +zuweisen zu können. Das Beispielprogramm versieht seine beiden +Panels mit einem eingelassenen Rahmen (Zeile 031 +und Zeile 051). Dazu +ist lediglich ein Aufruf der Methode setBorder +mit Übergabe einer Instanz der Klasse Border +erforderlich. Diese wird meist mit Hilfe einer der create-Methoden +der Klasse BorderFactory +erzeugt. + + + + +
+Eine JList +ist eine Liste von Werten, von denen einer oder mehrere ausgewählt +werden können. Ihre Bedienung ähnelt der aus dem AWT bekannten +Klasse List; +ihre Fähigkeiten gehen aber über diese hinaus. JList +ist ein gutes Beispiel für die Aufteilung der Swing-Komponenten +in Benutzerschnittstelle und Model. Anstatt - wie in unserem Beispiel +- einfach ein Array von festen Werten an den Konstruktor zu übergeben, +können mit Hilfe eines Listenmodells (repräsentiert durch +eine Instanz der Klasse ListModel) +sehr komplexe und dynamische Datenstrukturen in der Liste präsentiert +werden. Auch die Benutzeroberfläche ist veränderbar. Mit +Hilfe eigener »Renderer« können neben einfachen Texten +beispielsweise auch Grafiken oder andere Objekte angezeigt werden. + +
+In Zeile 036 kann man +noch eine Besonderheit sehen. Eine JList +bietet standardmäßig keine Möglichkeit zum Scrollen +ihres Inhalts. Wird sie ohne weitere Maßnahmen auf dem Panel +platziert, können nur Elemente aus dem sichtbaren Bereich ausgewählt +werden. Dieses Eigenschaft teilt sie mit anderen komplexen Swing-Elementen. +Glücklicherweise gibt es eine einfache Lösung für dieses +Problem. Die Liste ist nämlich lediglich in eine JScrollPane +einzubetten, die an ihrer Stelle auf dem Dialog platziert wird. Dieses +vielseitige Dialogelement versieht Dialogelemente, die mehr Platz +benötigen, als auf dem Bildschirm zur Verfügung steht, mit +Schiebereglern und kümmert sich um alle Details des Scrollens +der Daten. + + + + +
+Als letztes Dialogelement in unserem Beispiel wird die Klasse JButton +verwendet. Sie dient zur Darstellung von Schaltflächen und erbt +die meisten Eigenschaften aus ihrer Vaterklasse AbstractButton +(die ihre Eigenschaften übrigens auch an Menüeinträge +vererbt). Wie im Programm zu sehen, entsprechen die Grundlagen der +Bedienung von JButton +denen der Klasse Button. + + + + +
+Wie in Abschnitt 35.1.2 +erwähnt, kann das Look-and-Feel von Swing-Programmen zur Laufzeit +umgeschaltet werden. Im Beispielprogramm ist das ab Zeile 061 +zu sehen. Abhängig davon, welcher Button gedrückt wurde, +wird der Variablen plaf der +Klassenname einer Look-and-Feel-Implementierung zugewiesen. Durch +Aufruf der Methode setLookAndFeel +wird der UIManager +angewiesen, das Look-and-Feel umzuschalten. Damit die Änderungen +auch bei bereits auf dem Bildschirm befindlichen Dialogelementen sichtbar +werden, wird anschließend durch Aufruf von updateComponentTreeUI +der Klasse SwingUtilities +der gesamte Dialog neu dargestellt. +
+
![]() |
+
+
+ +Schlägt der Aufruf von setLookAndFeel +fehl (was je nach Plattform durchaus passieren kann), löst die +Methode eine Ausnahme des Typs UnsupportedLookAndFeelException +oder eine der Instanzierungsausnahmen aus. Das Programm sollte diese +Ausnahme abfangen, das bestehende Look-and-Feel aktiviert lassen und +den Anwender darüber in Kenntnis setzen. |
+
+
|
+![]() |
+
| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |