vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Woche 3

Tag 20


Benutzerschnittstellen mit Swing

In letzten zwei Tagen dieses Buches werden Sie mit einer Reihe von Klassen arbeiten, die sich Swing nennen. Mit diesen können Sie Benutzerschnittstellen mit einem Stil, der als Metal bezeichnet wird, implementieren.

Das klingt fast so, als ob einer bei JavaSoft entweder ein Musikfan oder ein frustrierter Musiker ist. Die nächste Technologie, die sich den Namen einer Musikrichtung entleiht, sollte Ska, Hiphop oder Bierfaß-Polka heißen.

Swing bietet gegenüber seinem Vorgänger eine wesentlich verbesserte Funktionalität - neue Komponenten, erweiterte Features der Komponenten, bessere Ereignisbehandlung und ein auswählbares Look and Feel.

Heute verwenden Sie Swing, um Java-Benutzerschnittstellen zu erstellen, und morgen lernen Sie, wie Sie diese Schnittstellen in vollwertige Programme verwandeln.


Swing ist auch als separates Add-On für Java 1.1 verfügbar. Wenn Sie ein Applet oder eine Applikation mit dem JDK 1.1 anstelle des JDK 1.2 schreiben, dann können Sie die Swing-Klassen verwenden, indem Sie sich die 1.1-kompatible Version der Java Foundation Classes von JavaSoft herunterladen. Momentan stehen diese auf der folgenden Seite zur Verfügung:

http://java.sun.com/products/jfc/

Da Swing in Java 1.2 vollständig integriert wurde, müssen Sie Swing nicht extra herunterladen, wenn Sie diese Version des JDK verwenden.

Die Vorteile von Swing

Look and Feel ist ein Ausdruck, der oft bei Erklärungen zur Programmierung von Benutzerschnittstellen verwendet wird. Die Bedeutung ist weitestgehend selbsterklärend - der Begriff beschreibt, wie eine Benutzerschnittstelle aussieht (Look) und wie sie sich für den Benutzer »anfühlt« (Feel) - anfühlen natürlich in bezug auf die Bedienung der Schnittstelle.

Swing ermöglicht es einem Java-Programm, ein unterschiedliches Look and Feel zu verwenden, gesteuert vom Programm selbst oder sogar durch den Benutzer.

Dieses Feature stellt die dramatischste Veränderung gegenüber dem AWT dar. Swing ermöglicht es Ihnen, ein Java-Programm mit einer Benutzerschnittstelle im Stil des jeweiligen Betriebssystems - z.B. Windows oder Solaris - oder einem Stil, der einzigartig bei Java ist (Dubbed Metal), zu erstellen.

Swing-Komponenten sind, anders als ihre Vorläufer in den vorherigen Versionen von Java, komplett in Java implementiert. Das hat eine bessere Kompatibilität zwischen den Programmen über unterschiedliche Plattformen hinweg zur Folge, als dies bei Programmen, die Sie mit dem Abstract Windowing Toolkit erzeugt haben, der Fall ist.

Alle Elemente von Swing sind Bestandteil des Paketes javax.swing. Um eine Swing- Klasse zu verwenden, müssen Sie entweder eine import-Anweisung für die jeweilige Klasse oder eines für alle Klassen des Paketes wie im folgenden verwenden:

import javax.swing.*;

Der Prozeß bei der Verwendung der Swing-Komponenten ist nicht anders als bei Komponenten des Abstract Windowing Toolkit. Sie erzeugen eine Komponente, indem Sie deren Konstruktor aufrufen, Methoden der Komponente aufrufen, falls diese für die korrekte Einrichtung nötig sind, und die Komponente in einen Container einfügen.


Swing verwendet dieselbe Infrastruktur bei den Klassen, wie das beim AWT der Fall ist, wodurch es möglich wird, Swing- und AWT-Komponenten auf derselben Benutzerschnittstelle zu mischen. Allerdings werden die beiden Komponententypen zusammen in einem Container in manchen Fällen nicht korrekt dargestellt. Um diese Probleme zu vermeiden, ist es am besten, ausschließlich ein System in einem Programm zu verwenden.

Swing-Komponenten sind alle Subklassen der Klasse JComponent.

Ein Applikationsgerüst

Der erste Schritt bei der Erstellung einer einfachen Swing-Applikation ist es, eine Klasse zu erzeugen, die eine Subklasse der Klasse JFrame ist. Die Klasse JFrame ist eine Erweiterung der Klasse Frame und kann auf ähnliche Art und Weise verwendet werden.

Der Code in Listing 20.1 kann als Gerüst für jede beliebige Applikation dienen, die Sie erstellen und die ein Hauptfenster verwendet.

Listing 20.1: Der gesamte Quelltext von Framework.java

 1: import java.awt.GridLayout;
 2: import java.awt.event.*;
 3: import javax.swing.*;
 4:


 5: public class Framework extends JFrame {
 6:
 7:     public Framework() {
 8:         super("Application Title");
 9:
10:         // Hier die Komponenten einfügen
11:     }
12:
13:     public static void main(String[] args) {
14:         JFrame frame = new Framework();
15:
16:         WindowListener l = new WindowAdapter() {
17:             public void windowClosing(WindowEvent e) {
18:                 System.exit(0);
19:             }
20:         };
21:         frame.addWindowListener(l);
22:
23:         frame.pack();
24:         frame.setVisible(true);
25:     }
26: }

Diese Applikation ist eine Subklasse von JFrame. Die gesamte Arbeit zur Erstellung der Benutzerschnittstelle des Frames wird im Konstruktor Framework() erledigt.

Zeile 8 des Konstruktors gibt einen Text für die Titelleiste des Frame an. Dazu wird die Methode super(String) verwendet. Die Benutzerschnittstelle sollte in diesem Konstruktor erstellt werden - hier können Komponenten in Container eingefügt werden und Container in den Frame.

In der main()-Methode der Applikation passiert folgendes:

Obwohl Sie dieses Gerüst erfolgreich kompilieren können, erzeugt es nichts Nützliches - das Fenster öffnet sich mit der minimal möglichen Größe, und Sie werden noch nicht einmal die Titelleiste in voller Länge sehen können.

Komponenten müssen hinzugefügt werden, bevor das Ganze beginnt, wie eine richtige Applikation auszusehen.

Komponenten in einen Swing-Frame einfügen


Die Arbeit mit einem JFrame-Objekt ist komplizierter als mit seinem AWT-Gegenstück. Anstatt Container und Komponenten direkt in den Frame einzufügen, müssen Sie diese in einen Zwischen-Container, der als content pane (Inhaltsbereich) bezeichnet wird, einfügen.

Ein JFrame ist in verschiedene Bereiche (panes) unterteilt. Der Hauptbereich, mit dem Sie arbeiten, ist der Inhaltsbereich. Dieser repräsentiert die gesamte Fläche des Frame, in die Komponenten eingefügt werden können.

Um eine Komponente in den Inhaltsbereich einzufügen, tun Sie folgendes:

Das Programm in Listing 20.2 verwendet das Applikationsgerüst und fügt eine Schaltfläche in den Inhaltsbereich des Frame ein. Die Schaltfläche wird mit der Klasse JButton erzeugt, die Swing-Version einer anklickbaren Schaltfläche.

Listing 20.2: Der gesamte Quelltext von Swinger.java

 1: import java.awt.GridLayout;
 2: import java.awt.event.*;
 3: import javax.swing.*;
 4:
 5: public class Swinger extends JFrame {
 6:
 7:     public Swinger() {
 8:         super("Swinger");
 9:
10:         String note = "I receive a disproportionate amount of " +
11:             "joy from being clicked. Please interact with me.";
12:         JButton hotButton = new JButton(note);
13:
14:         JPanel pane = new JPanel();
15:         pane.add(hotButton);
16:
17:         setContentPane(pane);
18:     }
19:
20:     public static void main(String[] args) {
21:         JFrame frame = new Swinger();
22:
23:         WindowListener l = new WindowAdapter() {
24:             public void windowClosing(WindowEvent e) {
25:                 System.exit(0);
26:             }
27:         };
28:         frame.addWindowListener(l);
29:
30:         frame.pack();
31:         frame.setVisible(true);
32:     }
33: }

Abbildung 20.1 zeigt die Ausgabe dieser Applikation.


Abbildung 20.1:
Die Swinger-Applikation

Das einzige neue Material in Listing 20.2 findet sich in den Zeilen 10 bis 17. Hier passiert folgendes:

Sobald Sie den Inhaltsbereich für einen Frame festgelegt haben, verwenden Sie Methoden wie setLayout(LayoutManager) und add(Component) für diesen Bereich. Sie können diese Methoden nicht direkt für den Frame selbst aufrufen.


Dies trifft ebenfalls für Applets zu, die in Swing mit der Klasse JApplet implementiert sind. Sie müssen ein JPanel-Objekt erzeugen, Komponenten in dieses einfügen und dann das Panel zum Inhaltsbereich des Applet machen. Beachten Sie aber bitte, daß alle Applets, die Sie mit Swing und Java 1.2 erstellen, nicht mit Webbrowsern zusammenarbeiten, die lediglich Java 1.02 unterstützen. Sie müssen außerdem einen Weg finden, die Swing-Klassen für das Applet verfügbar zu machen. Die Klassen benötigen zusammen mit den Dateien, die zu dem Applet gehören, viel Zeit für den Download von der Website.

Der Umgang mit Swing

Zu jeder Komponente des Abstract Windowing Toolkit, die Sie bisher kennengelernt haben, gibt es entsprechende Swing-Komponenten. In den meisten Fällen gibt es einen Konstruktor für eine Swing-Komponente, der dem AWT-Gengenstück entspricht, so daß Sie nichts Neues lernen müssen, um mit Swing zu arbeiten.


Für viele Komponenten gibt es auch neue Konstruktoren, die ein Icon-Objekt als Argument erwarten. Ein Icon ist eine kleine Grafik, normalerweise im GIF-Format, die auf einer Schaltfläche, einem Label oder anderen Elementen der Benutzerschnittstelle verwendet werden kann, um diese Komponente zu identifizieren. In Form von Dateiordnern sehen Sie Icons auf grafischen Betriebssystemen wie Windows 95 und MacOS ständig.

Ein Icon-Objekt wird ganz ähnlich wie ein Image-Objekt erzeugt. Der Konstruktor erwartet den Dateinamen der Grafik oder die URL als einziges Argument. Das folgende Beispiel lädt ein Icon aus der Datei unabom.gif und erzeugt ein JButton-Objekt mit diesem Icon als Label. Abbildung 20.2 zeigt das Ergebnis.

ImageIcon una = new ImageIcon("unabom.gif");
JButton button = new JButton(una);

JPanel pane = new JPanel();
pane.add(button);

setContentPane(pane);


Abbildung 20.2:
Ein Icon auf einem JButton-Objekt


Das Unabomber-Icon stammt von Jeffrey Zeldmans Icon-Sammlung »Pardon My Icons!«. Diese beinhaltet Hunderte von Icons, die Sie in Ihren eigenen Projekten verwenden können. Wenn Sie nach Icons suchen, mit denen Sie in Swing-Applikationen spielen können, dann sollten Sie sich mal auf der Pardon-My-Icons!-Website unter der folgenden Adresse umsehen:

http://www.zeldman.com

Der Quellcode zu diesem Beispiel steht auf der CD-ROM zu diesem Buch zur Verfügung. Der Name der Datei ist UnaButton.java, und das Icon befindet sich in der Datei unabom.gif.

Labels

Labels werden in Swing mit der Klasse JLabel implementiert. Die Funktionalität ist mit der der AWT-Labels vergleichbar. Allerdings können Sie inzwischen Icons verwenden. Zusätzlich kann die Ausrichtung eines Labels mit einer von 5 Klassenvariablen aus der Klasse SwingConstants festgelegt werden: LEFT, CENTER, RIGHT, LEADING oder TRAILING.

Unter anderem können Sie die folgenden Konstruktoren verwenden:

Schaltflächen

Wie Sie bereits gelernt haben, werden Swing-Schaltflächen über die Klasse JButton implementiert. Auf diesen kann sich ein Text-Label befinden, wie das bei AWT-Buttons der Fall ist, ein Icon-Label oder eine Kombination aus beiden.

Unter anderem können Sie die folgenden Konstruktoren verwenden:

Textfelder

Textfelder werden in Swing über die Klasse JTextField implementiert. Ein Unterschied zwischen diesen Textfeldern und ihren Gegenstücken aus dem AWT ist, daß die Methode setEchoChar(char) zur Verdeckung des eingegebenen Textes in JTextField nicht unterstützt wird.

Unter anderem können Sie die folgenden Konstruktoren verwenden:

Die Klasse JPasswordField wird verwendet, um ein Textfeld zu erzeugen, das den eingegebenen Text mit einem Zeichen verdeckt. Diese Klasse verfügt über dieselben Konstruktoren wie JTextField: JPasswordField(int) und JPasswordField(String, int).

Nachdem Sie ein Kennwortfeld erzeugt haben, können Sie die Methode setEchoChar(char) darauf anwenden, um das Zeichen festzulegen, mit dem die Eingabe verdeckt wird.

Mehrzeilige Textfelder (Textbereiche)

Textbereiche werden in Swing mit der Klasse JTextArea implementiert. Diese besitzt die folgenden Konstruktoren:

Kontrollkästchen und Optionsfelder

Die Klasse JCheckBox stellt die Implementierung von Kontrollkästchen in Swing dar. Die Funktionalität entspricht der des AWT-Gegenstücks mit der Erweiterung, daß Icons als Labels unterstützt werden.

Unter anderem können Sie die folgenden Konstruktoren verwenden:

Kontrollkästchengruppen werden in Swing mit der Klasse ButtonGroup implementiert. Wie Sie gesehen haben, kann in einer Kontrollkästchengruppe immer nur ein Kontrollkästchen zugleich markiert sein. Sie erzeugen ein ButtonGroup-Objekt und fügen Kontrollkästchen mit der add(Component)-Methode in die Gruppe ein.

Optionsfelder werden in Swing über die Klasse JRadioButton implementiert. Die Konstruktoren entsprechen denen der Klasse JCheckBox.

Die Namensänderung von CheckboxGroup zu ButtonGroup spiegelt die erweiterte Funktionalität wider - Schaltflächen und Optionsfelder können ebenfalls hiermit gruppiert werden.

Listenfelder

Listenfelder, wie sie im AWT mit der Klasse Choice erzeugt wurden, sind nur eine Möglichkeit, die Sie mit der Klasse JComboBox von Swing haben.

Ein Listenfeld wird über die folgenden Schritte erzeugt:

1. Der Konstruktor JComboBox() wird ohne Argumente aufgerufen.

2. Mit der Methode addItem(Object) des erzeugten Objekts werden der Liste Einträge hinzugefügt.

3. Die Methode setEditable(boolean) des Objekts wird mit false als Argument aufgerufen.

Diese letzte Methode sorgt dafür, daß ein Listenfeld entsteht - die einzigen Wahlmöglichkeiten für den Benutzer sind die Einträge, die zuvor in die Liste eingefügt wurden. Falls das JComboBox-Objekt editierbar ist, kann der Benutzer Text als Alternative zur Auswahl eines Eintrages in der Liste eingeben. Diese Kombination gibt den Kombinationslistenfeldern ihren Namen.

Bildlaufleisten

Bildlaufleisten werden in Swing über die Klasse JScrollBar implementiert. Die Funktionalität ist identisch mit der der AWT-Bildlaufleisten. Die folgenden Konstruktoren können Sie verwenden:

Die Orientierung wird über die Variablen HORIZONTAL bzw. VERTICAL der Klasse SwingConstants festgelegt.

Ein Beispiel: die Applikation SwingColorTest

Eines der Projekte an Tag 14 war das Applet ColorTest, das die Auswahl einer Farbe über deren sRGB- oder HSB-Werte ermöglichte.

Das nächste Projekt erzeugt eine grafische Oberfläche für dieses Projekt mit Swing. Anstatt eines Applets erstellen wir hier eine Applikation. Die Methoden zur Ereignisbehandlung werden Sie morgen erzeugen.

Listing 20.3: Der gesamte Quelltext von SwingColorTest.java

 1: import java.awt.*;
 2: import java.awt.event.*;
 3: import javax.swing.*;
 4:
 5: public class SwingColorTest extends JFrame {
 6:     SwingColorControls RGBcontrols, HSBcontrols;
 7:     JPanel swatch;
 8:
 9:     public SwingColorTest() {
10:         super("Color Test");
11:
12:         JPanel pane = new JPanel();
13:         pane.setLayout(new GridLayout(1, 3, 5, 15));
14:         swatch = new JPanel();
15:         swatch.setBackground(Color.black);
16:         RGBcontrols = new SwingColorControls(this, "Red",
17:             "Green", "Blue");
18:         HSBcontrols = new SwingColorControls(this, "Hue",
19:             "Saturation", "Brightness");
20:         pane.add(swatch);
21:         pane.add(RGBcontrols);
22:         pane.add(HSBcontrols);
23:
24:         setContentPane(pane);
25:     }
26:
27:     public static void main(String[] args) {
28:         JFrame frame = new SwingColorTest();
29:
30:         WindowListener l = new WindowAdapter() {
31:             public void windowClosing(WindowEvent e) {
32:                 System.exit(0);
33:             }
34:         };
35:         frame.addWindowListener(l);
36:
37:         frame.pack();
38:         frame.setVisible(true);
39:     }
40:
41:     public Insets getInsets() {
42:         return new Insets(10, 10, 10, 10);
43:     }
44: }
45:
46: class SwingColorControls extends JPanel {
47:     SwingColorTest frame;
48:     JTextField tfield1, tfield2, tfield3;
49:
50:     SwingColorControls(SwingColorTest parent,
51:         String l1, String l2, String l3) {
52:
53:         frame = parent;
54:         setLayout(new GridLayout(3,2,10,10));
55:         tfield1 = new JTextField("0");
56:         tfield2 = new JTextField("0");
57:         tfield3 = new JTextField("0");
58:         add(new JLabel(l1, JLabel.RIGHT));
59:         add(tfield1);
60:         add(new JLabel(l2, JLabel.RIGHT));
61:         add(tfield2);
62:         add(new JLabel(l3, JLabel.RIGHT));
63:         add(tfield3);
64:     }
65:
66:     public Insets getInsets() {
67:         return new Insets(10, 10, 0, 0);
68:     }
69: }

Abbildung 20.3 zeigt die Benutzerschnittstelle, die wir für diese Applikation entworfen haben. Obwohl die Schaltflächen und andere Komponenten ein anderes Look and Feel als das ColorTest-Applet an den Tag legen (darüber lernen Sie im Abschnitt »Das Look and Feel festlegen« mehr), funktioniert der Rest der Benutzerschnittstelle, wie das bei den Nicht-Swing-Gegenstücken der Fall ist.


Abbildung 20.3:
Die SwingColorTest-Applikation

Das SwingColorTest-Programm verwendet das Applikationsgerüst, das weiter oben eingeführt wurde, so daß viele Teile des Programms bereits früher vorgestellt wurden.

Dieses Programm besteht aus drei Klassen: Der Hauptklasse SwingColorTest, der als private deklarierten Hilfsklasse SwingColorControls und einer Internen Klasse, die in den Zeilen 30 bis 34 definiert ist.

Sowohl die Klasse SwingColorTest als auch die Klasse SwingColorControls überschreiben die Methode getInsets(). Dies ermöglicht es den Komponenten, von dem Rand des Containers eine bestimmte Anzahl von Pixeln abgesetzt zu werden. Wie auch bei vielen anderen Aspekten von Swing wird dies in derselben Art und Weise unterstützt, wie das bei AWT-Komponenten der Fall ist.

Die Klasse SwingColorControls ist eine Subklasse der Klasse JPanel. Diese Klasse wurde für Swing aktualisiert. Dazu wurden die AWT-Komponenten Textfelder und Labels gegen Swing-Komponenten ausgetauscht. Ansonsten waren keine anderen Änderungen notwendig.

In der Klasse SwingColorTest aktualisierten die folgenden Änderungen den Code für die Benutzerschnittstelle, so daß anstelle des AWT Swing verwendet wird:

In vielen Fällen kann eine Benutzerschnittstelle, die mit dem Abstract Windowing Toolkit erzeugt wurde, mit wenigen wesentlichen Änderungen mit Swing implementiert werden. Wenn Sie ein Applet, das mit Java 1.02 geschrieben wurde, in ein Swing-Programm für Java 1.2 konvertieren wollen, dann kommen größere Änderungen im Bereich der Ereignisbehandlungsmethoden, die morgen behandelt werden, auf Sie zu.

Neue Features von Swing

Zusätzlich zu Komponenten und Containern, die die Funktionalität des Abstract Windowing Toolkit erweitern, bietet Swing noch viele Features, die vollkommen neu sind. Dazu gehören das definierbare Look and Feel, Tastatur-Mnemonics (Tastaturkürzel), ToolTips und Standarddialogfelder.

Das Look and Feel festlegen

Sie sind bereits mit dem Konzept der Layout-Manager vertraut - Klassen, die die Anordnung von Komponenten auf einer Benutzerschnittstelle kontrollieren.

Swing besitzt einen Manager für Benutzerschnittstellen, der das Look and Feel von Komponenten kontrolliert - die Art, in der Schaltflächen, Labels und andere Elemente auf dem Bildschirm dargestellt werden.

Das Management des Look and Feel wird von der Klasse UIManager im Paket übernommen. Die Auswahlmöglichkeiten, die Ihnen zur Verfügung stehen, hängen davon ab, welche Java-Entwicklungsumgebung Sie verwenden. Folgendes steht zur Verfügung:

Die Klasse UIManager verfügt über die Methode setLookAndFeel(LookAndFeel). Diese wird dazu verwendet, um das Look and Feel eines Programmes zu wählen.

Um ein LookAndFeel-Objekt zu erhalten, das Sie in der Methode setLookAndFeel(LookAndFeel) verwenden können, verwenden Sie die folgenden Methoden der Klasse UIManager:

Die Methode setLookAndFeel(LookAndFeel) wirft eine Ausnahme aus, wenn sie das Look and Feel nicht setzen kann.

Die folgenden Anweisungen können in einem beliebigen Programm dazu verwendet werden, Metal als Look and Feel festzulegen:

try {
    UIManager.setLookAndFeel(
        UIManager.getCrossPlatformLookAndFeelClassName());
    } catch (Exception e) {
        System.err.println("Can't set look and feel: " + e);
}

Um das Look and Feel Ihres Systems zu wählen, verwenden Sie die Methode getSystemLookAndFeelClassName() als Argument für die Methode setLookAndFeel() im vorigen Beispiel. Dies erzeugt unterschiedliche Ergebnisse auf unterschiedlichen Betriebssystemen. Ein Windows-95-Benutzer erhält über getSystemLookAndFeelClassName() das Look and Feel von Windows 95. Ein Unix-Anwender würde das Motif Look and Feel erhalten.

Tastatur-Mnemonics


Ein Tastatur-Mnemonic (auch Tastaturkürzel oder Tastaturshortcut genannt) ist eine Tastenfolge, die zur Steuerung einer Komponente der Benutzerschnittstelle verwendet werden kann. Dies stellt einen Weg zur Verfügung, mit dem ein Programm ohne Maus verwendet werden kann. Tastatur, Mnemonics sind Teil der Unterstützung von Accessibility-Features durch Swing - neue Klassen, die es Blinden oder anderen Leuten mit Behinderungen ermöglichen, ein Java-Programm auszuführen.

Tastatur-Mnemonics simulieren eine Mausaktion, sobald sie verwendet werden. Die Art, wie Mnemonics verwendet werden, unterscheidet sich je nach Plattform. Auf einem Computer, auf dem Windows 95 installiert ist, wird ein Tastatur-Mnemonic verfügbar, indem man die ALT-Taste in Kombination mit einer anderen Taste drückt.

Tastatur-Mnemonics werden über den Aufruf der Methode setMnemonic(char) der Komponente, die über dieses Tastatur-Mnemonic gesteuert werden soll, gesetzt. Das char-Argument ist die Taste, die als Teil des Tastatur-Mnemonic verwendet werden soll. Das folgende Beispiel erzeugt ein JButton-Objekt und verknüpft den Buchstaben 'i' mit der Schaltfläche:

JButton infoButton = new JButton("Information");
infoButton.setMnemonic('i');

Das Drücken der Tastenkombination [ALT]+[I] entspricht einem Anklicken der Schaltfläche.

ToolTips

Eine andere Methode, ein Programm benutzerfreundlicher zu gestalten, stellt die Verknüpfung von ToolTips mit Komponenten auf einer Benutzerschnittstelle dar. Sie werden eventuell schon mit ToolTips vertraut sein - kleine Textfahnen, die in einigen Programmen angezeigt werden, wenn Ihre Maus einige Sekunden über einer Komponente verharrt.

ToolTips werden dazu verwendet, den Zweck einer Komponente zu beschreiben. Wenn Sie die Bedienung eines Programmes erlernen, stellen ToolTips - sofern sie implementiert wurden - eine exzellente Lernhilfe dar.

Um einen ToolTip für eine Komponente zu setzen, rufen Sie die Methode setToolTipText(String) für die jeweilige Komponente auf. Der String sollte eine knappe Beschreibung der Aufgabe der Komponente sein.

Das folgende Beispiel erzeugt eine JScrollBar-Komponente und verknüpft einen ToolTip mit dieser:

JScrollBar speed = new JScrollBar();
speed.setToolTipText("Move to set animation speed");

Der Text für den ToolTip ist auf eine Zeile begrenzt. Aus diesem Grund können Sie die Escape-Sequenz für einen Zeilenumbruch (»\n«) nicht verwenden, um den Text in mehrere Zeilen aufzuteilen.

Komponentenbeschreibungen und -namen

Eine weitere Möglichkeit, eine Benutzerschnittstelle leichter zugänglich zu machen, ist, einen Beschreibungstext anzubieten. Dies wird über einen zweistufigen Prozeß umgesetzt:

1. Über einen Aufruf der Methode getAccessibleContext() der Komponente das AccessibleContext-Objekt, das der Komponente zugewiesen ist, ermitteln.

2. Aufrufen der Methode setAccessibleDescription(String) des AccessibleContext -Objektes. Das String-Argument sollte die Beschreibung der Komponente sein.

Das folgende Beispiel setzt die Beschreibung eines JButton-Objekts:

JButton quit = new JButton("Quit");
quit.getAccessibleContext().setAccessibleDescription(
    "When you click this button, the program terminates.");

Die Methode setAccessibleName(String) funktioniert auf die gleiche Weise wie die Methode setAccessibleDescription(String). Diese Methode kann dazu verwendet werden, einer Komponente einen Namen zu geben, der ihren Zweck kurz beschreibt. »Quit-Schaltfläche« wäre ein geeigneter Name für das quit-Objekt im vorigen Beispiel. Das nächste Beispiel setzt den Namen für das Textfeld nm auf "Namens-Feld":

JTextField nm = new JTextField();
nm.getAccessibleContext().setAccessibleName("Namens-Feld");

Standarddialogfelder

Die Klasse JOptionPane enthält einige Methoden, die zur Erzeugung von Standarddialogfeldern verwendet werden können: kleine Fenster, die eine Frage stellen, einen Benutzer warnen oder eine kurze wichtige Meldung anzeigen. Abbildung 20.4 zeigt ein Beispiel eines Dialogfeldes im Metal-Look-and-Feel.

Zweifellos haben Sie schon derartige Dialogfelder gesehen - wenn sich Ihr System aufhängt, zeigt ein Dialogfeld diese unerfreuliche Nachricht an, wenn Sie Dateien löschen, fragt Sie ein Dialogfeld, ob Sie dies wirklich tun wollen. Diese Fenster sind ein effektiver Weg, mit einem Benutzer zu kommunizieren, ohne den Overhead, neue Klassen zu erstellen, die diese Fenster repräsentieren, Komponenten in diese einzufügen und den Code für die Ereignisbehandlung der Benutzereingaben schreiben zu müssen. Alle diese Dinge werden automatisch erledigt, wenn eines der Standarddialogfelder von JOptionPane verwendet wird.


Abbildung 20.4: Ein Standarddialogfeld.

Es gibt vier Standarddialogfelder:

Jedes dieser Dialogfelder hat seine eigene Methode in der Klasse JOptionPane.

ConfirmDialog-Dialogfelder

Den einfachsten Weg, ein Yes/No/Cancel-Dialogfeld zu erzeugen, stellt der folgende Methodenaufruf dar: showConfirmDialog(Component, Object) ). Das Argument Component gibt den Container an, dem das Dialogfeld zugeordnet sein soll. Diese Information wird dazu verwendet, festzulegen, wo am Bildschirm das Dialogfeld angezeigt werden soll. Wenn anstelle eines Containers Null verwendet wird oder wenn der Container kein Frame-Objekt ist, dann wird das Dialogfeld auf dem Bildschirm zentriert.

Das zweite Argument kann ein String, eine Komponente oder ein Icon-Objekt sein. Wenn es ein String ist, dann wird dieser Text in dem Dialogfeld angezeigt. Wenn es sich dagegen um eine Komponente oder ein Icon handelt, dann wird dieses Objekt anstelle einer Textmeldung angezeigt.

Diese Methode gibt einen von drei möglichen Integer-Werten zurück. Jeder davon ist eine Klassenvariable von JOptionPane: YES_OPTION, NO_OPTION und CANCEL_OPTION.

Das folgende Beispiel verwendet ein Dialogfeld vom Typ ConfirmDialog mit einer Textmeldung und speichert die Antwort in der Variablen response:

int response;
response = JOptionPane.showConfirmDialog(null,
    "Should I delete all of your irreplaceable personal files");

Eine andere Methode bietet mehr Optionen für Dialogfelder des Typs ConfirmDialog: showConfirmDialog(Component, Object, String, int, int). Die ersten beiden Argumente entsprechen denen der anderen showConfirmDialog()-Methode. Die letzten drei werden im folgenden beschrieben:

int response = JOptionPane.showConfirmDialog(null,
            "Error reading file. Want to try again?",
            "File Input Error",
            JOptionPane.YES_NO_OPTION,
            JOptionPane.ERROR_MESSAGE);

In Abbildung 20.5 sehen Sie das Dialogfeld, das das obige Beispiel erzeugt, im Windows-Look-and-Feel.


Abbildung 20.5:
Ein Dialogfeld vom Typ ConfirmDialog

InputDialog-Dialogfelder

Ein Dialogfeld des Typs InputDialog stellt eine Frage und verwendet ein Textfeld, um die Anwort zu speichern. Abbildung 20.6 zeigt ein Beispiel, das das Motif-Look-and- Feel verwendet.


Abbildung 20.6:
Ein Dialogfeld vom Typ InputDialog

Der einfachste Weg, ein Dialogfeld des Typs InputDialog zu erstellen, ist ein Aufruf der Methode showInputDialog(Component, Object). Die Argumente sind der Container, dem das Dialogfeld zugeordnet ist, und der String, die Komponente oder das Icon, das in dem Dialogfeld angezeigt werden soll.

Der Aufruf der Methode gibt einen String zurück, der die Antwort des Benutzers repräsentiert. Die folgende Anweisung erzeugt das Dialogfeld, das in Abbildung 20.6 gezeigt ist:

String response = JOptionPane.showInputDialog(null,
    "Enter your name:");

Sie können ein solches Dialogfeld auch mit der Methode showInputDialog(Component, Object, String, int) erzeugen. Die ersten beiden Argumente entsprechen dem kürzeren Methodenaufruf und die letzten beiden werden im folgenden erklärt:

Die folgende Anweisung erzeugt ein Dialogfeld vom Typ InputDialog mit der oben beschriebenen Methode:

String response = JOptionPane.showInputDialog(null,
    "What is your ZIP code?",
    "Enter ZIP Code",
    JOptionPane.QUESTION_MESSAGE);

MessageDialog-Dialogfelder

Dialogfelder des Typs MessageDialog sind einfache Fenster, die Informationen anzeigen. In Abbildung 20.7 sehen Sie ein Beispiel im Metal-Look-and-Feel.


Abbildung 20.7:
Ein Dialogfeld vom Typ MessageDialog

Ein solches Dialogfeld kann über einen Aufruf der Methode showMessageDialog(Component, Object) erzeugt werden. Wie bei den anderen Dialogfeldtypen stellen die Argumente den zugeordneten Container und den anzuzeigenden String, die Komponente oder das Icon dar.

Anders als bei den anderen Dialogfeldtypen gibt diese Art Dialogfeld keinerlei Wert zurück. Die folgende Anweisung erzeugt das Dialogfeld aus Abbildung 20.7:

JOptionPane.showMessageDialog(null,
    "The program has been uninstalled.");

Zusätzlich können Sie ein Dialogfeld dieses Typs mit der Methode showMessageDialog(Component, Object) erzeugen. Die Anwendung entspricht der der Methode showInputDialog() mit denselben Argumenten. Einziger Unterschied: Die Methode gibt keinen Wert zurück.

Die folgende Anweisung erzeugt ein Dialogfeld des Typs mit dieser Methode:

String response = JOptionPane.showMessageDialog(null,
    "An asteroid has destroyed the Earth.",
    "Asteroid Destruction Alert",
    JOptionPane.WARNING_MESSAGE);

OptionDialog-Dialogfelder

Dialogfelder des Typs OptionDialog stellen die komplexeste Art dar. Diese Dialogfelder kombinieren die Features aller anderen Dialogfeldarten. Sie können mit der Methode showOptionDialog(Component, Object, String, int, int, Icon, Object[], Object) erzeugt werden.

Die Argumente der Methode haben die folgende Bedeutung:

Die beiden letzten Argumente ermöglichen es Ihnen, in dem Dialogfeld eine große Anzahl von Wahlmöglichkeiten zu erstellen. Sie können ein Array mit Schaltflächen, Textfeldern oder sogar mit einer Mischung unterschiedlicher Komponenten als Objekt-Array erzeugen. Diese Komponenten werden mit dem FlowLayout-Layout-Manager angeordnet - es besteht keine Möglichkeit, einen anderen Layout-Manager für diesen Dialog zu wählen.

Das folgende Beispiel erzeugt ein Dialogfeld, das ein Array mit JButton-Objekten als Wahlmöglichkeit in dem Dialogfeld verwendet. Das gender[2]-Element wird als Standardauswahl festgelegt:

JButton[] gender = new JButton[3];
gender[0] = new JButton("Male");
gender[1] = new JButton("Female");
gender[2] = new JButton("None of Your Business");
int response = JOptionPane.showOptionDialog(null,
    "What is your gender?",
    "Gender",
    0,
    JOptionPane.INFORMATION_MESSAGE,
    null,
    gender,
    gender[2]);

Abbildung 20.8 zeigt das Dialogfeld, das sich aus diesem Code ergibt, im Motif-Look- and-Feel.


Abbildung 20.8:
Ein Dialogfeld vom Typ OptionDialog

Ein Beispiel: die Info-Applikation

Das nächste Projekt bietet eine Chance, eine Reihe von Dialogfeldern in einem funktionierenden Programm zu erleben. Die Info-Applikation verwendet Dialogfelder, um Informationen vom Benutzer zu ermitteln. Diese Informationen werden anschließend im Hauptfenster der Applikation in Textfeldern plaziert.

Tippen Sie doch das Listing 20.4 ab, und kompilieren Sie das Ganze.

Listing 20.4: Der gesamte Quelltext von Info.java.

 1: import java.awt.GridLayout;
 2: import java.awt.event.*;
 3: import javax.swing.*;
 4:
 5: public class Info extends JFrame {
 6:     private JLabel titleLabel = new JLabel("Title: ",
 7:         SwingConstants.RIGHT);
 8:     private JTextField title;
 9:     private JLabel addressLabel = new JLabel("Address: ",
10:         SwingConstants.RIGHT);
11:     private JTextField address;
12:     private JLabel typeLabel = new JLabel("Type: ",
13:         SwingConstants.RIGHT);
14:     private JTextField type;
15:
16:     public Info() {
17:         super("Site Information");
18:
19:         // Site-Name
20:         String response1 = JOptionPane.showInputDialog(null,
21:             "Enter the site title:");
22:         title = new JTextField(response1, 20);
23:
24:         // Site-Addresse
25:         String response2 = JOptionPane.showInputDialog(null,
26:             "Enter the site address:");
27:         address = new JTextField(response2, 20);
28:
29:         // Site-Art
30:         String[] choices = { "Personal", "Commercial", "Unknown" };
31:         int response3 = JOptionPane.showOptionDialog(null,
32:             "What type of site is it?",
33:             "Site Type",
34:             0,
35:             JOptionPane.QUESTION_MESSAGE,
36:             null,
37:             choices,
38:             choices[0]);
39:         type = new JTextField(choices[response3], 20);
40:
41:         JPanel pane = new JPanel();
42:         pane.setLayout(new GridLayout(3, 2));
43:         pane.add(titleLabel);
44:         pane.add(title);
45:         pane.add(addressLabel);
46:         pane.add(address);
47:         pane.add(typeLabel);
48:         pane.add(type);
49:
50:         setContentPane(pane);
51:     }
52:
53:     public static void main(String[] args) {
54:         try {
55:             UIManager.setLookAndFeel(
56:                 UIManager.getSystemLookAndFeelClassName());
57:         } catch (Exception e) {
58:             System.err.println("Couldn't use the system "
59:                              + "look and feel: " + e);
60:         }
61:
62:         JFrame frame = new Info();
63:
64:         WindowListener l = new WindowAdapter() {
65:             public void windowClosing(WindowEvent e) {
66:                 System.exit(0);
67:             }
68:         };
69:         frame.addWindowListener(l);
70:
71:         frame.pack();
72:         frame.setVisible(true);
73:     }
74: }

Abbildung 20.9 zeigt das Hauptfenster der Applikation im systemeigenen Look and Feel (in diesem Screenshot ist es Windows). Drei Textfelder beinhalten Werte, die sie aus Dialogfeldern erhalten.


Abbildung 20.9:
Das Hauptfenster der Info-Applikation

Ein großer Teil dieser Applikation ist vorgefertigter Code, der bei jeder Swing-Applikation verwendet werden kann. Die folgenden Zeilen beziehen sich auf die Dialogfelder:


Abbildung 20.10:
Das Dialogfeld zum Abfragen des Typs der Site

Zusammenfassung

Nachdem viele hunderttausend Programmierer die Chance hatten, die ersten Versionen von Java zu verwenden, zielten die meisten Beschwerden auf das Abstract Windowing Toolkit ab. Obwohl es die Erstellung einer funktionellen Benutzerschnittstelle erlaubt, gab es einige Probleme, alle Benutzerschnittstellen auf unterschiedlichen Plattformen zum Laufen zu bringen. Außerdem wurden einige Elemente einer grafischen Benutzeroberfläche nicht vom AWT unterstützt.

Swing ist eine effektive Antwort auf diese Kritik. Es bietet ein ausgefeiltes System zur Erstellung grafischer Benutzeroberflächen, das sich für viele unterschiedliche Arten von Java-Programmen einsetzen läßt. Wenn Sie einen Blick in die Dokumentation von Swing werfen, werden Sie mehr als 30 verschiedene Komponenten finden.

Morgen werden Sie lernen, eine Benutzerschnittstelle in eine vollständige Applikation zu verwandeln.

Fragen und Antworten

Frage:
Kann eine Applikation auch ohne Swing erstellt werden?

Antwort:
Sicherlich - Swing ist lediglich eine Erweiterung des Abstract Windowing Toolkit, und Sie können auch unter Java 1.2 weiterhin das AWT für Applikationen verwenden. Sie sollten lediglich die Techniken zur Ereignisbehandlung, die Sie morgen lernen, anstelle der Techniken für Java-1.02-Applets verwenden. Ob Sie eine Applikation ohne Swing erstellen sollten, ist eine andere Frage. Es werden im AWT keine zu Swing vergleichbaren Möglichkeiten angeboten. Mit Swing können Sie weitaus mehr Komponenten auf eine viel ausgefeiltere Art verwenden.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Ein Imprint des Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: Java 2 in 21 Tagen, ISBN: 3-8272-5578-3