Programmieren in Java: Aufbau
Dieses Buch ist unter einer Creative Commons-Lizenz lizensiert.
Das AWT - kurz für Abstract Window Toolkit - ist eine Ansammlung von Klassen, um grafische Schaltelemente in einem Java-Programm einzusetzen. Zu diesen Schaltelementen gehören beispielsweise Kombinationsschaltflächen, Kontrollkästchen oder auch einfache anklickbare Schaltflächen. Mit diesen Klassen ist es möglich, unkompliziert übersichtliche Benutzerschnittstellen aufzubauen. Da das AWT seit der allerersten Java-Version 1.0 fest in die Java-Klassenhierarchie gehört, können derartige grafische Anwendungen dank der Portabilität von Java auf allen Betriebssystemen laufen.
Wenn Sie sich mit Java-Applets ein wenig auskennen, wissen Sie, dass Applets eine Methode paint()
kennen. Diese kann vom Programmierer überschrieben werden, um beispielsweise Texte an ganz bestimmten Positionen in der Applet-Oberfläche auszugeben. Die Ausgabe von Text mit paint()
oder andere Zeichenoperationen, die in dieser Methode ausgeführt werden können, stellen eher den primitiven Zugriff dar, der für kleinere Anwendungen völlig ausreichend sein kann. Wollen Sie dem Anwender jedoch eine Schnittstelle bieten, die den gleichen Komfort besitzt wie Windows-Anwendungen, ist das AWT genau das Richtige für Sie.
Innerhalb der Java-Klassenhierarchie liegen die AWT-Klassen in ihrem eigenen Paket, und zwar in java.awt. Möchten Sie ein Benutzerinterface mit Hilfe von AWT-Klassen erstellen, sollten Sie alle Klassen dieses Pakets mit import
einbinden.
Dieses Kapitel erklärt Aufbau und Verwendung des AWT aus Java 1.1. Das AWT in Java 1.0 ist veraltet und sollte nicht mehr verwendet werden. Java 1.2 bietet neben dem AWT eine neue bessere Klassenansammlung, um grafische Interfaces zu entwickeln: Das Swing-Framework. Swing ist ein völlig neuer Ansatz und hat nichts mit AWT zu tun, steht jedoch erst ab Java 1.2 zur Verfügung.
Das Java-Paket java.awt besteht in Java 1.1 aus etwa 50 Klassen. Die interessantesten Klassen werden im Folgenden in aller Kürze vorgestellt.
Die wichtigsten Klassen, um Schaltflächen zu zeichnen, sind folgende.
java.awt.Button
ist eine Klasse, um anklickbare Schaltflächen zu erstellen. und , wie man sie aus vielen Windows-Dialogfenstern kennt, werden in Java genau mit dieser Klasse realisiert.
java.awt.Label
ist eine Schaltfläche, die Text enthält. Der Anwender kann keine Aktionen mit dieser Schaltfläche durchführen. Ein Objekt dieses Typs stellt lediglich eine Anzeigemöglichkeit für Text dar.
java.awt.TextField
stellt ein einzeiliges Texteingabefeld für den Anwender dar.
java.awt.TextArea
stellt ein mehrzeiliges Texteingabefeld für den Anwender dar.
java.awt.Checkbox
und java.awt.CheckboxGroup
werden benötigt, wenn Kontrollkästchen erstellt und zu Gruppen zusammengefasst werden sollen. Kontrollkästchen kommen immer dann zum Einsatz, wenn der Anwender genau eine aus mehreren Optionen auswählen darf.
java.awt.Choice
ist eine Kombinationsschaltfläche.
java.awt.List
präsentiert dem Anwender eine Auswahlmöglichkeit in Form einer Liste.
java.awt.PopupMenu
ermöglicht die Entwicklung von Popup-Menüs. Sie kennen diese Menüs aus Microsoft Windows, wenn Sie mit der rechten Maustaste beispielsweise im Desktop klicken - es öffnet sich dann ein Popup-Menü.
java.awt.Scrollbar
stellt Scrollbars zur Verfügung. Diese Klasse kann auch zweckentfremdet werden, um sie beispielsweise als Schieberegler einzusetzen.
Hilfsklassen, die die Arbeit mit AWT-Klassen unterstützen, sind folgende.
java.awt.Color
wurde in vielen Beispielen im Buch Programmieren in Java: Einführung verwendet. Wann immer Sie mit Farben arbeiten müssen, bietet sich die Verwendung dieser Klasse an. Viele Methoden, beispielsweise zum Festlegen von Vorder- und Hintergrundfarben, erwarten als Parameter ein Objekt dieses Typs.
java.awt.Dimension
kapselt Höhe und Breite eines Elements. Anstatt also Höhe und Breite als getrennte Werte beispielsweise einer Methode zu übergeben, können sie in einem Objekt dieses Typs gespeichert werden, das dann seinerseits als einziger Parameter übergeben wird.
java.awt.Point
ist eine Hilfsklasse, die zwei Eigenschaften vom Typ int
besitzt und normalerweise verwendet wird, um Koordinaten zu speichern.
Klassen, um Fenster zu öffnen oder anderweitig mit Fenstern zu arbeiten, stehen folgende in AWT zur Verfügung.
java.awt.Frame
erstellt Fenster mit Titelleiste und Menü und kann darüberhinaus ein Icon als Fenstersymbol erhalten. Diese Klasse ist Grundlage für das Entwickeln gewöhnlicher Fenster.
java.awt.Dialog
steht zur Verfügung, um ein Dialogfenster zu öffnen. Ein Dialogfenster ist eigentlich nicht mehr als eine primitive Fläche, auf der Schaltflächen angezeigt werden können. Dialogfenster bieten keine Möglichkeit, Titelleisten oder Menüs einzublenden. Daher eignet sich diese Klasse eher für kurze und knappe Benutzereingaben, beispielsweise für Sicherheitsabfragen beim Beenden einer Anwendung.
java.awt.FileDialog
stellt ein vorgefertigtes Dialogfenster dar, um Dateien im Dateisystem zu suchen. Diese Klasse bietet sich hervorragend an, wenn Dateien geöffnet oder gespeichert werden sollen.
Folgende Klassen werden verwendet, um Menüs zu erzeugen.
java.awt.MenuBar
stellt eine Menüleiste dar.
java.awt.Menu
ist ein sich öffnendes Menü in einer Menüleiste.
java.awt.MenuItem
ist ein Eintrag innerhalb eines Menüs.
java.awt.CheckboxMenuItem
ist ein Eintrag innerhalb eines Menüs, der ein Kontrollkästchen enthält.
java.awt.MenuShortcut
ist eine Tastenkombination, die mit einem Menüeintrag verknüpft werden kann, so dass durch die Tastenkombination der entsprechende Menüeintrag aktiviert wird.
Java bedient sich sogenannter Layout Manager, um Schaltflächen auszurichten. Folgende Layout Manager stehen in Java im AWT zur Verfügung. Sinn und Zweck von Layout Managern wird anschließend im Kapitel erläutert.
java.awt.BorderLayout
unterteilt eine Fläche in die vier Himmelsrichtungen und ein Zentrum.
java.awt.CardLayout
erstellt eine Registerkarten-Schaltfläche. Derartige Schaltelemente eignen sich, um sehr viele Schaltflächen auf engem Raum unterzubringen und gleichzeitig zu gruppieren.
java.awt.FlowLayout
ordnet Schaltflächen der Reihe nach von links nach rechts und von oben nach unten an - also in der gleichen Art und Weise wie ein Textverlauf. Diese Klasse ist der Standard-Layout-Manager von Java-Applets.
java.awt.GridLayout
ordnet Schaltflächen in Tabellenform an, wobei beim Erstellen eines Objekts dieses Typs angegeben werden kann, wie viele Zeilen und Spalten das Layout erhalten soll.
java.awt.GridBagLayout
ist der komplizierteste und gleichzeitig flexibelste Layout Manager. Schaltflächen werden in einer Tabelle angeordnet, wobei nun Schaltflächen auch den Platz mehrere Felder in einer Zeile oder Spalte einnehmen können. Schaltflächen besitzen keine Einheitsgröße mehr wie bei java.awt.GridLayout
.
Sonstige interessante AWT-Klassen sind folgende.
java.awt.Container
verkörpert die Fähigkeit, andere AWT-Klassen in sich aufzunehmen. Eine Klasse, die von java.awt.Container
abgeleitet ist, kann grafische Schaltflächen aufnehmen und innerhalb ihrer Oberfläche zeichnen. Eine prominente von java.awt.Container
abgeleitete Klasse ist java.applet.Applet
. Ein Java-Applet kann daher Schaltflächen basierend auf AWT-Klassen in seiner Oberfläche anzeigen.
java.awt.Cursor
bietet Zugriff auf die Darstellung des Mauszeigers. Er kann beispielsweise in ein Fadenkreuz oder eine Hand umgewandelt werden.
java.awt.Font
ermöglicht die Bearbeitung einer Schrift, um sie danach auf bestimmte Schaltflächen anzuwenden.
java.awt.Image
verwaltet Grafiken.
java.awt.Insets
repräsentiert den leeren Raum um eine Schaltfläche herum - also den Rand, in dem keine andere Schaltfläche liegen darf.
java.awt.MediaTracker
lernen Sie im Kapitel 3, Grafik und Sound näher kennen. Diese Klasse steuert den Ladevorgang von Grafiken. Wenn die benötigten Grafiken geladen sind, wird eine andere Klasse informiert, so dass dann die Ausgabe der Grafiken zum Beispiel in einem Applet erfolgen kann.
java.awt.SystemColor
bietet Zugriff auf Farben, die vom Computer-System standardmäßig verschiedenen Schaltflächen wie zum Beispiel Menüs zugewiesen werden. Indem die entsprechenden Farben dieser Klasse entnommen werden, kann eine Java-Anwendung für die Darstellung der Schaltflächen die gleichen Farben verwenden, wie sie der Anwender momentan für sein Computer-System eingestellt hat. Diese Klasse wird näher im Kapitel 6, Systemzugriff vorgestellt.
Dieses Buch stellt in einem eigenen Kapitel detailliert den Einsatz von Swing-Klassen vor, um mit diesen seit Java 1.2 existierenden Klassen Benutzerschnittstellen zu entwickeln. Die oben vorgestellten Klassen werden in Swing bis auf wenige Ausnahmen nicht verwendet, so dass es leider notwendig ist, für Swing völlig neue Klassen zu erlernen.
Die Programmiersprache Java verfolgt den Ansatz der Portabilität. Portable Anwendungen können auf den verschiedensten Geräten laufen. Eine portable Anwendung kann nicht davon ausgehen, jeweils eine ganz bestimmte und feste Größe an Anzeigeplatz zu besitzen. Eine portable Anwendung sollte versuchen, aus dem jeweils zur Verfügung stehenden Platz das Beste zu machen. Layout Manager sind das ideale Werkzeug, Platz optimal für die Anzeige von Schaltflächen in Anspruch zu nehmen.
Die Klasse java.awt.Container
besitzt eine Methode setLayout()
. java.applet.Applet
ist unter anderem von dieser Klasse abgeleitet, so dass Sie auch für Java-Applets diese Methode aufrufen können. Mit setLayout()
können Sie einen Layout Manager angeben, den Sie für Ihr Applet oder Ihre Application verwenden möchten. Je nachdem, welchen Layout Manager Sie wählen, werden Schaltflächen anders angeordnet. Java-Applets verwenden standardmäßig den Layout Manager java.awt.FlowLayout
.
Betrachten Sie folgendes Beispiel, in dem drei Schaltflächen mit Hilfe des standardmäßigen Layout Managers java.awt.FlowLayout
im Java-Applet ausgerichtet werden.
import java.applet.*; import java.awt.*; public class MyApplet extends Applet { Button MyButton1, MyButton2, MyButton3; public void init() { MyButton1 = new Button("MyButton 1"); MyButton2 = new Button("MyButton 2"); MyButton3 = new Button("MyButton 3"); add(MyButton1); add(MyButton2); add(MyButton3); } }
Der Layout Manager java.awt.FlowLayout
fügt Schaltflächen zeilenweise in die Oberfläche ein, und jeweils zentriert. Ist die erste Zeile voll, wird die nächste Schaltfläche, die mit add()
dem Container hinzugefügt wird, in die nächste Zeile gepackt - und dort natürlich auch wieder zentriert. Es spielt also überhaupt keine Rolle, wieviel Platz das Applet tatsächlich in der Webseite erhalten hat - der Layout Manager übernimmt vollautomatisch die richtige Anordnung der Schaltflächen im zur Verfügung stehenden Platz.
java.awt.BorderLayout
unterteilt den zur Verfügung stehenden Platz in fünf Felder, die den Himmelsrichtungen und einem Zentrum zugeordnet werden. Wenn nun eine Schaltfläche einem Container hinzugefügt wird, der sich des Layout Managers java.awt.BorderLayout
bedient, kann beim Aufruf von add()
angegeben werden, in welchem der fünf Felder die Schaltfläche platziert werden soll.
import java.applet.*; import java.awt.*; public class MyApplet extends Applet { Button MyButton1, MyButton2, MyButton3; public void init() { setLayout(new BorderLayout()); MyButton1 = new Button("MyButton 1"); MyButton2 = new Button("MyButton 2"); MyButton3 = new Button("MyButton 3"); add(MyButton1, BorderLayout.WEST); add(MyButton2, BorderLayout.NORTH); add(MyButton3, BorderLayout.EAST); } }
Als zweiter Parameter wird der Methode add()
eine statische Konstante der Klasse java.awt.BorderLayout
übergeben, die festlegt, wo im Container die Schaltfläche platziert wird. Bevor jedoch die Methode add()
zum ersten Mal aufgerufen wird, wird setLayout()
ein Objekt der Klasse java.awt.BorderLayout
übergeben und der Layout Manager gewechselt.
Die Layout Manager java.awt.CardLayout
, java.awt.GridLayout
und java.awt.GridBagLayout
werden ähnlich verwendet, erfordern jedoch ein paar Zeilen Java-Code mehr. Sie werden nicht näher vorgestellt, da sich grundsätzlich die Frage stellt, wie sinnvoll Layout Manager sind. Auf der einen Seite besitzen sie den Vorteil, den zur Verfügung stehenden Platz automatisch optimal auszunutzen. Auf der anderen Seite zeichnen sie eine Benutzerschnittstelle, die wohl in den wenigsten Fällen als schön bezeichnet werden kann und kaum mit übersichtlichen Fenstern aus Windows-Anwendungen konkurrieren kann.
Die meisten Entwickler gehen sicherlich davon aus, dass ihrem Java-Applet ein ganz bestimmter Platz in einer Webseite eingeräumt wird. Verwendet ein anderer Benutzer das Java-Applet derart, dass er diesem weniger Platz einräumt als vom Java-Applet benötigt, ist das sein Problem und nicht das des Entwicklers. Die Wahrscheinlichkeit, dass das Java-Applet auf Geräten wie beispielsweise Java-Armbanduhren laufen wird, die aufgrund ihrer Größe nur sehr wenig Platz bereitstellen können, ist sehr gering. Die Entwicklung professioneller Java-Applets findet daher normalerweise ohne Layout Manager statt: Schaltflächen werden pixelgenau ausgerichtet. Die dadurch gewonnene Kontrolle über den Aufbau der Benutzerschnittstelle ermöglicht übersichtliche und elegante Schnittstellen, in denen Schaltflächen nicht zwanghaft bemüht sind, soviel Platz wie möglich an sich zu reißen oder in einer Einheitsgröße die Schnittstelle zu bevölkern.
Um Schaltflächen durch Angabe von Koordinaten auszurichten, wird kein Layout Manager mehr benötigt. Sie rufen daher folgende Methode auf, um den standardmäßigen Layout Manager - bei Java-Applets java.awt.FlowLayout
- zu deaktivieren.
setLayout(null);
Indem Sie den Parameter null
der Methode setLayout()
übergeben, wird der Layout Manager deaktiviert. Die Ausrichtung von Schaltflächen müssen Sie nun selber übernehmen. Dazu stehen Ihnen folgende Methoden zur Verfügung.
setSize()
legt Höhe und Breite einer Schaltfläche fest.
setLocation()
legt die Koordinate fest, an der die linke obere Ecke der Schaltfläche liegen soll.
setBounds()
legt die Koordinate für die linke obere Ecke und gleichzeitig Höhe und Breite der Schaltfläche fest.
Alle drei Methoden erwarten Parameter vom Typ int
. Sie können stattdessen auch die Parameter in Objekte vom Typ der Hilfsklassen java.awt.Dimension
, java.awt.Point
oder java.awt.Rectangle
packen und dann das entsprechende Objekt als jeweils einzigen Parameter an die Methode übergeben.
Im folgenden Beispiel werden drei Schaltflächen untereinander ausgerichtet, wobei eine Schaltfläche jeweils doppelt so groß wie die vorherige ist.
import java.applet.*; import java.awt.*; public class MyApplet extends Applet { Button MyButton1, MyButton2, MyButton3; public void init() { setLayout(null); MyButton1 = new Button("MyButton 1"); MyButton2 = new Button("MyButton 2"); MyButton3 = new Button("MyButton 3"); MyButton1.setBounds(10, 10, 100, 50); MyButton2.setBounds(10, 70, 200, 100); MyButton3.setBounds(10, 180, 400, 200); add(MyButton1); add(MyButton2); add(MyButton3); } }
Beachten Sie, dass der Aufruf von setBounds()
zum Ausrichten der Schaltflächen vor dem Aufruf von add()
stattfindet. Sie können also Schaltflächen im Speicher formatieren, um sie dann mit den entsprechenden Vorgaben im Applet erscheinen zu lassen. Sie sollten grundsätzlich immer alle notwendigen Schritte zum Bearbeiten einer Schaltfläche ausführen, bevor Sie die Schaltfläche auf einer Oberfläche mit add()
platzieren.
Eine Benutzerschnittstelle macht nur dann Sinn, wenn sie auf Eingaben des Anwenders reagiert. Es muss schliesslich irgendetwas passieren, wenn der Anwender auf eine Schaltfläche klickt. Zum Teil funktionieren Schaltflächen völlig automatisch. Wenn Sie ein paar Kontrollkästchen anlegen und sie zu einer Gruppe zusammenfassen, darf jeweils nur eine einzige Option aktiviert sein. Markiert der Anwender eine andere Option, wird die vorherige demarkiert - ohne dass Sie dies erst noch programmieren müssten. Das folgende Beispiel veranschaulicht dies.
import java.applet.*; import java.awt.*; public class MyApplet extends Applet { Checkbox MyCheckbox1, MyCheckbox2, MyCheckbox3; CheckboxGroup MyCheckboxGroup; public void init() { setLayout(new GridLayout(3, 1)); MyCheckboxGroup = new CheckboxGroup(); MyCheckbox1 = new Checkbox("MyCheckbox 1", MyCheckboxGroup, true); MyCheckbox2 = new Checkbox("MyCheckbox 2", MyCheckboxGroup, false); MyCheckbox3 = new Checkbox("MyCheckbox 3", MyCheckboxGroup, false); add(MyCheckbox1); add(MyCheckbox2); add(MyCheckbox3); } }
Obiges Beispiel verwendet den Layout Manager java.awt.GridLayout
, um eine Tabelle bestehend aus drei Zeilen und einer Spalte anzulegen. In die drei Felder der Tabelle werden per add()
drei Objekte vom Typ java.awt.Checkbox
gelegt. Die drei Kontrollkästchen werden zu einer Gruppe zusammengefasst, indem ein Objekt vom Typ java.awt.CheckboxGroup
erstellt wird und dieses Objekt jeweils als zweiter Parameter dem Konstruktor von java.awt.Checkbox
übergeben wird. Der dritte Parameter im Konstruktor gibt übrigens an, ob das Kontrollkästchen anfangs aktiviert oder nicht aktiviert sein soll.
Das Beispiel von eben erhält nun zusätzlich eine anklickbare Schaltfläche. Während die Klasse java.awt.Button
zur Darstellung eines derartigen grafischen Elements gut geeignet ist, passiert nichts, wenn der Anwender auf die Schaltfläche klickt. Sie müssen die entsprechende Aktion selber programmieren.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class MyApplet extends Applet implements MouseListener { Checkbox MyCheckbox1, MyCheckbox2, MyCheckbox3; CheckboxGroup MyCheckboxGroup; Button MyButton; public void init() { setLayout(new GridLayout(4, 1)); MyCheckboxGroup = new CheckboxGroup(); MyCheckbox1 = new Checkbox("MyCheckbox 1", MyCheckboxGroup, true); MyCheckbox2 = new Checkbox("MyCheckbox 2", MyCheckboxGroup, false); MyCheckbox3 = new Checkbox("MyCheckbox 3", MyCheckboxGroup, false); MyButton = new Button("MyButton"); MyButton.addMouseListener(this); add(MyCheckbox1); add(MyCheckbox2); add(MyCheckbox3); add(MyButton); } public void mouseReleased(MouseEvent ev) { Checkbox Active = MyCheckboxGroup.getSelectedCheckbox(); MyButton.setLabel(Active.getLabel()); } public void mousePressed(MouseEvent ev) { } public void mouseEntered(MouseEvent ev) { } public void mouseExited(MouseEvent ev) { } public void mouseClicked(MouseEvent ev) { } }
Um auf Benutzereingaben reagieren zu können, müssen Sie entsprechende Events abfangen. Je nachdem, welche Aktion der Anwender ausführt, werden unterschiedliche Events ausgelöst, treten also unterschiedliche Ereignisse ein. Das Paket java.awt.event enthält eine Reihe von Interfaces und Klassen, die wichtig sind, um auf Benutzereingaben reagieren zu können. Indem Sie ein Interface einbinden und die entsprechenden Methoden definieren, bereiten Sie die Klasse auf das Eintreten bestimmter Ereignisse vor. Jedes Interface deklariert Methoden, die in ganz bestimmten Situationen, beispielsweise bei Loslassen einer Maustaste, automatisch aufgerufen werden. Indem Sie die Methoden des Interfaces definieren, legen Sie fest, was bei Benutzereingaben passieren soll.
Die interessantesten Interfaces inklusive der Methoden, die sie deklarieren, werden im Folgenden kurz vorgestellt. Bei welchen Ereignissen die Methoden jeweils aufgerufen werden, ergibt sich teilweise aus ihrem Namen.
java.awt.event.KeyListener
wird benötigt, um auf Tastatureingaben reagieren zu können. Das Interface deklariert die drei abstrakten Methoden keyPressed()
, keyReleased()
und keyTyped()
. Allen Methoden wird bei einem Aufruf vom Java-System ein Parameter vom Typ java.awt.event.KeyEvent
übergeben, der weitere Informationen zum Ereignis enthält.
java.awt.event.FocusListener
ist ein Interface, um auf den Erhalt und den Verlust des Fokus reagieren zu können. Das heißt, die zwei abstrakten Methoden focusGained()
und focusLost()
werden dann aufgerufen, wenn eine Schaltfläche markiert wurde oder die Markierung verloren hat. Man spricht hierbei vom Fokus. Beiden Methoden wird bei einem Aufruf vom Java-System ein Parameter vom Typ java.awt.event.FocusEvent
übergeben.
java.awt.event.MouseListener
reagiert auf Maus-Ereignisse. Das Interface deklariert die fünf abstrakten Methoden mouseClicked()
, mouseEntered()
, mouseExited()
, mousePressed()
und mouseReleased()
. Allen Methoden wird bei einem Aufruf vom Java-System ein Parameter vom Typ java.awt.event.MouseEvent
übergeben, der weitere Informationen zum Ereignis enthält.
java.awt.event.MouseMotionListener
deklariert Methoden, um auf Bewegungen der Maus zu reagieren. Das Interface besteht aus den beiden abstrakten Methoden mouseDragged()
und mouseMoved()
. Den Methoden wird bei einem Aufruf vom Java-System ein Parameter vom Typ java.awt.event.MouseEvent
übergeben, der weitere Informationen zum Ereignis enthält.
java.awt.event.TextListener
ist ein Interface, um auf Textänderungen zu reagieren. Es deklariert die abstrakte Methode textValueChanged()
, der beim Aufruf vom Java-System ein Parameter vom Typ java.awt.event.TextEvent
mit weiteren Informationen zum Ereignis übergeben wird.
java.awt.event.WindowListener
verwenden Sie, wenn Sie auf Ereignisse reagieren möchten, die ein Fenster betreffen. Das können beispielsweise das Maximieren oder das Schließen eines Fensters sein. Das Interface deklariert die sieben abstrakten Methoden windowActivated()
, windowClosed()
, windowClosing()
, windowDeactivated()
, windowDeiconified()
, windowIconified()
und windowOpened()
. Allen Methoden wird bei einem Aufruf vom Java-System ein Parameter vom Typ java.awt.event.WindowEvent
übergeben, der weitere Informationen zum Ereignis enthält.
Wie Sie sehen implementiert das vorherige Beispiel das Interface java.awt.MouseListener
. Lediglich die Methode mouseReleased()
besitzt einen Methodenrumpf, der tatsächlich etwas tut. Die Methode wird automatisch aufgerufen, wenn eine Maustaste losgelassen wird. Die Frage ist, wohin muss der Anwender eigentlich klicken, um dann die Maustaste loszulassen und die Methode mouseReleased()
aufzurufen? Schließlich gibt es mehrere Schaltflächen im Applet.
Damit das Java-System tatsächlich Ereignisse registriert und weiterleitet, muss für das Objekt eine entsprechende Methode aufgerufen werden. Um beispielsweise Mausereignisse für die Schaltfläche im vorherigen Beispiel abfangen zu können, wird für das Objekt MyButton die Methode addMouseListener()
aufgerufen. Diese Methode ist in der Klasse java.awt.Component
definiert, von der viele AWT-Klassen abgeleitet sind. Daher ist es für die meisten Schaltflächen kein Problem, addMouseListener()
aufzurufen und somit auf Mausereignisse auf der jeweiligen Schaltfläche zu reagieren.
addMouseListener()
muss ein Parameter vom Typ java.awt.event.MouseListener
übergeben werden - also ein Objekt einer Klasse, die das Interface java.awt.event.MouseListener
implementiert. Dieses Objekt ist es, dessen Methoden aufgerufen werden und das letztendlich die entsprechenden Anweisungen enthält, um auf die Benutzereingabe zu reagieren.
Während mit addMouseListener()
auf Mausereignisse für ein Objekt reagiert werden kann, stehen addKeyListener()
, addMouseMotionListener()
und addFocusListener()
zur Verfügung, um auf Tastatureingaben, Mausbewegung und den Fokus zu reagieren. Auch diesen Methoden wird ein Objekt als Parameter übergeben, das das jeweilige Interface implementieren muss und die Methoden enthält, die bei Eintreten von Ereignissen aufgerufen werden.
In diesem Abschnitt vollziehen Sie Schritt für Schritt die Entwicklung einer kleinen Java-Anwendung nach. Es soll ein Java-Applet mit einer Schaltfläche im Browser eingeblendet werden. Klickt der Anwender auf diese, öffnet sich ein Java-Fenster. Das Fenster präsentiert dem Anwender zwei Textfelder, in die er seine Körpergröße und sein Gewicht eingeben kann. Klickt er auf eine Schaltfläche, die sich ebenfalls im Java-Fenster befindet, wird eine Meldung ausgegeben, ob der Anwender Normalgewicht hat oder möglicherweise über- oder untergewichtig ist. Das Programm verwendet hierzu den sogenannten Body-Mass-Index, der berechnet wird, indem das Körpergewicht ins Verhältnis zur Körpergröße im Quadrat gesetzt wird.
Beachten Sie, dass es sich hierbei um eine Beispiel-Anwendung in Java handelt, die den Einsatz von AWT-Klassen vorstellen soll. Verwenden Sie diese Beispiel-Anwendung nicht, um in irgendeiner Weise medizinische Rückschlüsse zu ziehen.
import java.applet.*; import java.awt.*; public class MyApplet extends Applet { Button Start; public void init() { setLayout(new BorderLayout()); Start = new Button("Start"); add(Start, BorderLayout.CENTER); } }
Als erster Schritt wird eine Schaltfläche dem Java-Applet hinzugefügt, über die später das neue Java-Fenster geöffnet werden soll. Die Schaltfläche soll zentriert im Java-Applet angezeigt werden. Dazu wird mit setLayout()
der Layout Manager auf java.awt.BorderLayout
gesetzt, nachdem dieser eine Zentrierung sehr einfach macht. Danach wird die Schaltfläche mit Hilfe der Klasse java.awt.Button
erstellt und abschließend mit add()
dem Applet hinzugefügt.
Das Java-Fenster, das die Eingabemöglichkeit für den Anwender enthalten soll, wird mit einer zweiten Klasse erstellt, um den Code übersichtlicher zu gestalten. Die Klasse bekommt den Namen MyFrame
, da sie von der Klasse java.awt.Frame
abgeleitet wird.
import java.awt.*; public class MyFrame extends Frame { Label LabelSize, LabelWeight, LabelResult; TextField TextSize, TextWeight; Button OK; public MyFrame() { setLayout(new GridLayout(3, 2)); setSize(400, 120); LabelSize = new Label("Ihre Körpergröße in cm:"); LabelWeight = new Label("Ihr Gewicht in kg:"); LabelResult = new Label(); TextSize = new TextField(); TextWeight = new TextField(); OK = new Button("OK"); add(LabelSize); add(TextSize); add(LabelWeight); add(TextWeight); add(LabelResult); add(OK); } }
Die Klasse MyFrame
erhält eine einzige Methode: Sie heißt MyFrame()
- also genauso wie die Klasse selber - und besitzt keinen Rückgabewert. Sie dürfen noch nicht einmal void
angeben. Bei dieser Methode handelt es sich um einen Konstruktor. Das heißt, diese Methode wird automatisch aufgerufen, wenn ein Objekt vom Typ dieser Klasse mit dem Schlüsselwort new
erstellt wird.
Innerhalb des Konstruktors wird mit setLayout()
der Layout Manager auf java.awt.GridLayout
gesetzt. Die Oberfläche des Fensters ist nun in eine Art Tabelle eingeteilt. Aus wie vielen Zeilen und Spalten die Tabelle besteht, wird als Parameter dem Konstruktor des Layout Managers übergeben. Beachten Sie, dass der erste Wert die Anzahl der Zeilen, der zweite Wert die Anzahl der Spalten festlegt.
Als nächstes wird über den Aufruf von setSize()
die Größe des Fensters festgelegt. Sie sollten diese Methode immer aufrufen, selbst wenn Ihnen mehr oder weniger egal ist, wie groß das Fenster genau sein soll. Rufen Sie setSize()
nicht auf, kann es sein, dass das Fenster so klein gezeichnet wird, dass der Anwender lediglich die Titelleiste sieht - was für unerfahrene Anwender ein Problem sein kann und außerdem nicht schön aussieht.
In den restlichen Zeilen des Konstruktors werden diverse Objekte erstellt, den Referenzvariablen zugewiesen, die als Eigenschaften der Klasse MyFrame
definiert sind, und die Objekte über add()
dem Fenster hinzugefügt. Die Reihenfolge, in der die Objekte an add()
übergeben werden, ist für den Layout Manager java.awt.GridLayout
entscheidend: Die Felder der Tabelle werden zeilenweise von links oben nach rechts unten gefüllt.
Als nächstes muss die Klasse MyFrame
dahingehend erweitert werden, dass eine Berechnung ausgeführt wird, wenn der Anwender Größe und Gewicht eingibt und auf die Schaltfläche klickt. Dazu wird das Interface java.awt.MouseListener
implementiert.
import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame implements MouseListener { Label LabelSize, LabelWeight, LabelResult; TextField TextSize, TextWeight; Button OK; public MyFrame() { setLayout(new GridLayout(3, 2)); setSize(400, 120); LabelSize = new Label("Ihre Körpergröße in cm:"); LabelWeight = new Label("Ihr Gewicht in kg:"); LabelResult = new Label(); TextSize = new TextField(); TextWeight = new TextField(); OK = new Button("OK"); OK.addMouseListener(this); add(LabelSize); add(TextSize); add(LabelWeight); add(TextWeight); add(LabelResult); add(OK); } public void mouseReleased(MouseEvent ev) { if (TextSize.getText().length > 0 && TextWeight.getText().length > 0) { try { int Size = Integer.parseInt(TextSize.getText()); int Weight = Integer.parseInt(TextWeight.getText()); double BMI = Weight / ((Size / 100.0) * (Size / 100.0)); if (BMI < 18.5) { LabelResult.setText("Sie haben möglicherweise Untergewicht."); } else if (BMI > 30) { LabelResult.setText("Sie haben möglicherweise starkes Übergewicht."); } else if (BMI > 25) { LabelResult.setText("Sie haben möglicherweise Übergewicht."); } else { LabelResult.setText("Sie haben Normalgewicht."); } } catch (NumberFormatException ex) { } } else { LabelResult.setText("Geben Sie Größe und Gewicht an."); } } public void mousePressed(MouseEvent ev) { } public void mouseEntered(MouseEvent ev) { } public void mouseExited(MouseEvent ev) { } public void mouseClicked(MouseEvent ev) { } }
Die Implementierung von java.awt.event.MouseListener
bedeutet, dass die fünf abstrakten Methoden des Interfaces definiert werden müssen. Außerdem muss für irgendein Objekt - in diesem Beispiel ist es die Schaltfläche - addMouseListener()
aufgerufen werden, um es für Mausereignisse zu registrieren.
Die Methode mouseReleased()
enthält die Berechnung für den Body-Mass-Index. Das Ergebnis dieser Berechnung wird in der Variablen BMI gespeichert. In Abhängigkeit des Ergebnisses wird über das Objekt LabelResult vom Typ java.awt.Label
durch Aufruf der Methode setText()
eine entsprechende Meldung direkt im Fenster ausgegeben. Fehlt eine Eingabe, wird stattdessen der Hinweis eingeblendet, dass Größe und Gewicht angegeben werden müssen.
Wenn Sie obiges Beispiel ausprobieren würden, stellen Sie fest, dass Sie das Java-Fenster nicht schließen können. Weder der Mausklick auf eine entsprechende Standard-Schaltfläche in der Titelleiste noch Tastenkombinationen bewegen das Fenster dazu zu verschwinden. Es hilft unter Umständen nur das Schließen sämtlicher Browser-Fenster, bis das Java-Fenster endlich verschwindet.
Damit bei einem Mausklick auf die Schließen-Schaltfläche in der Titelleiste das Fenster tatsächlich geschlossen wird, muss die Klasse MyFrame
das Interface java.awt.event.WindowListener
implementieren und speziell die Methode windowClosing()
definieren. Diese Methode ist es, die aufgerufen wird, wenn der Anwender versucht, das Fenster zu schließen. Damit das Fenster geschlossen wird, muss dies innerhalb dieser Methode programmiert werden.
import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame implements MouseListener, WindowListener { Label LabelSize, LabelWeight, LabelResult; TextField TextSize, TextWeight; Button OK; public MyFrame() { setLayout(new GridLayout(3, 2)); setSize(400, 120); LabelSize = new Label("Ihre Körpergröße in cm:"); LabelWeight = new Label("Ihr Gewicht in kg:"); LabelResult = new Label(); TextSize = new TextField(); TextWeight = new TextField(); OK = new Button("OK"); OK.addMouseListener(this); add(LabelSize); add(TextSize); add(LabelWeight); add(TextWeight); add(LabelResult); add(OK); addWindowListener(this); } public void mouseReleased(MouseEvent ev) { if (TextSize.getText().length() > 0 && TextWeight.getText().length() > 0) { try { int Size = Integer.parseInt(TextSize.getText()); int Weight = Integer.parseInt(TextWeight.getText()); double BMI = Weight / ((Size / 100.0) * (Size / 100.0)); if (BMI < 18.5) { LabelResult.setText("Sie haben möglicherweise Untergewicht."); } else if (BMI > 30) { LabelResult.setText("Sie haben möglicherweise starkes Übergewicht."); } else if (BMI > 25) { LabelResult.setText("Sie haben möglicherweise Übergewicht."); } else { LabelResult.setText("Sie haben Normalgewicht."); } } catch (NumberFormatException ex) { } } else { LabelResult.setText("Geben Sie Größe und Gewicht an."); } } public void mousePressed(MouseEvent ev) { } public void mouseEntered(MouseEvent ev) { } public void mouseExited(MouseEvent ev) { } public void mouseClicked(MouseEvent ev) { } public void windowClosing(WindowEvent ev) { setVisible(false); dispose(); } public void windowActivated(WindowEvent ev) { } public void windowClosed(WindowEvent ev) { } public void windowDeactivated(WindowEvent ev) { } public void windowDeiconified(WindowEvent ev) { } public void windowIconified(WindowEvent ev) { } public void windowOpened(WindowEvent ev) { } }
Um das Fenster tatsächlich zu schließen, wird es innerhalb der Methode windowClosing()
zuerst mit setVisible()
ausgeblendet und dann mit dispose()
aus dem Speicher gelöscht. Damit die Methode windowClosing()
auch aufgerufen wird, wenn der Anwender das Fenster schließen möchte, dürfen Sie nicht vergessen, addWindowListener()
im Konstruktor aufzurufen.
Die Klasse MyFrame
ist somit komplett. Was noch fehlt ist die Verknüpfung zur Klasse MyApplet
. Dort ist bisher lediglich eine Schaltfläche zentriert im Applet angelegt worden. Damit sich bei einem Mausklick auch tatsächlich das Java-Fenster öffnet, das in der Klasse MyFrame
entwickelt wurde, wird MyApplet
wie folgt ergänzt.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class MyApplet extends Applet implements MouseListener { Button Start; MyFrame Window; public void init() { setLayout(new BorderLayout()); Start = new Button("Start"); Start.addMouseListener(this); add(Start, BorderLayout.CENTER); Window = new MyFrame(); } public void mouseReleased(MouseEvent ev) { Window.setVisible(true); } public void mousePressed(MouseEvent ev) { } public void mouseEntered(MouseEvent ev) { } public void mouseExited(MouseEvent ev) { } public void mouseClicked(MouseEvent ev) { } }
Die gesamte Entwicklung grafischer Anwendungen mit AWT-Klassen basiert auf den Konzepten, wie Sie sie in diesem Kapitel kennengelernt haben. Die Art und Weise, wie Sie beim Erstellen von Benutzerschnittstellen vorgehen müssen, sollte Ihnen nun klar sein. Für die Arbeit in der Praxis sind detaillierte Unterlagen zu den einzelnen AWT-Klassen jedoch unerläßlich. Nur dort finden Sie die genaue Definition der unzähligen Methoden, die Sie für die AWT-Klassen aufrufen können. Das Einarbeiten in die Klassen und das nähere Kennenlernen des AWT kann Ihnen niemand abnehmen. Wenn Sie sich jedoch dieses Kapitel immer im Hinterkopf parat halten, sollten Sie auch diese Hürde problemlos meistern.
Sie können die Lösungen zu allen Aufgaben in diesem Buch als ZIP-Datei erwerben.
Erweitern Sie das Beispiel aus Abschnitt 1.5, „Benutzereingaben“ dahingehend, dass die Bezeichnung des ausgewählten Kontrollkästchens in der Schaltfläche nicht nur dann angezeigt wird, wenn der Anwender mit der Maus klickt, sondern auch, wenn die Schaltfläche per Tastatur aktiviert wird.
Schlagen Sie in der Dokumentation nach, welches Interface Sie benötigen, um auf Tastatureingaben auf Schaltflächen vom Typ java.awt.Button
zu reagieren. Es ist nicht java.awt.event.KeyListener
. Haben Sie das richtige Interface gefunden, können Sie die Funktionalität des Applets nicht nur erweitern, sondern auch den Code sehr verkürzen.
Entwickeln Sie ein Java-Applet, das eine Kombinationsschaltfläche enthält, über die der Anwender zwischen den drei Farben Rot, Grün und Blau wählen kann. Die jeweils gewählte Farbe wird für den Hintergrund des Applets gesetzt.
Zur Darstellung einer Kombinationsschaltfläche verwenden Sie die Klasse java.awt.Choice
. Um ein Ereignis abzufangen, wenn der Anwender einen Eintrag aus der Kombinationsschaltfläche wählt, müssen Sie das Interface java.awt.event.ItemListener
implementieren.
Entwickeln Sie ein Java-Applet, das eine einzeilige Texteingabebox und eine anklickbare Schaltfläche vom Typ java.awt.Button
enthält. Der Text, der vom Anwender in das Eingabeelement getippt wird, soll als Beschriftung für die Schaltfläche verwendet und in dem Moment gesetzt werden, wenn der Anwender die Schaltfläche mit der Maus oder Tastatur betätigt.
Sie benötigen die Klassen java.awt.TextField
und java.awt.Button
, um die Benutzerschnittstelle zu erstellen. Setzen Sie dann das Interface java.awt.event.ActionListener
ein, um bei Betätigen der Schaltfläche informiert zu werden und den vom Anwender eingegebenen Text als neue Beschriftung zu setzen.
Erweitern Sie Ihre Lösung zu Aufgabe 3 dahingehend, dass die neue Beschriftung nicht nur dann gesetzt wird, wenn die Schaltfläche vom Typ java.awt.Button
betätigt wird, sondern auch dann, wenn der Anwender im Texteingabefeld Enter drückt.
Setzen Sie das Interface java.awt.event.KeyListener
ein, um herauszufinden, wann der Anwender Enter drückt.
Erweitern Sie Ihre Lösung zu Aufgabe 4 dahingehend, dass eine zusätzliche Schaltfläche vom Typ java.awt.Label
jeweils anzeigt, welches Steuerelement momentan den Fokus besitzt.
Verwenden Sie das Interface java.awt.event.FocusListener
, um herauszufinden, wann ein Steuerelement den Fokus erhält und verliert.
Ändern Sie Ihre Lösung zu Aufgabe 5 dahingehend, dass Sie aus dem Java-Applet eine Java-Application machen. Modifizieren Sie Ihre Anwendung derart, dass bei Start der Application ein Fenster geöffnet wird, das die Benutzeroberfläche enthält, die Sie in den vorherigen Aufgaben für Ihr Java-Applet entwickelt haben. Beachten Sie, dass sich das Fenster Ihrer Anwendung tatsächlich schließt, wenn der Anwender eine entsprechende Aktion ausführt.
Um aus einem Applet eine Application zu machen, fügen Sie Ihrem Code eine öffentliche statische Methode main()
hinzu, die als Datentyp des Rückgabewertes void
besitzt und einen Parameter vom Typ eines Arrays vom Typ String
erwartet. Leiten Sie Ihre Klasse von java.awt.Frame
ab, erstellen Sie ein Objekt vom Typ Ihrer Klasse in der Methode main()
und rufen Sie für das Objekt die Methoden setSize()
und show()
auf, um für das Anwendungsfenster eine bestimmte Größe einzustellen und es am Bildschirm anzuzeigen. Ergänzen Sie Ihren Code um das Interface java.awt.event.WindowListener
, um das Fenster tatsächlich zu schließen, wenn der Anwender dies wünscht. Fügen Sie als letzte Code-Zeile der Methode windowClosing()
einen Aufruf der statischen Methode exit()
der Klasse java.lang.System
hinzu, um die Application komplett zu beenden, wenn das Fenster geschlossen wird.
Entwickeln Sie ein Java-Applet, das eine Scrolleiste enthält, über die vom Anwender stufenlos die Hintergrundfarbe des Applets zwischen Schwarz und Rot eingestellt werden kann.
Um eine Scrolleiste zu erstellen, greifen Sie auf die Klasse java.awt.Scrollbar
zu. Verwenden Sie das Interface java.awt.event.AdjustmentListener
, um informiert zu werden, wenn der Anwender die Scrolleiste benutzt.
Entwickeln Sie ein Java-Applet, in dem Sie jeweils drei Schaltflächen vom Typ java.awt.Button
auf vier Registerkarten des Layout Managers java.awt.CardLayout
anzeigen. Die vier Registerkarten sollen ihrerseits die Layout Manager java.awt.FlowLayout
, java.awt.BorderLayout
, java.awt.GridLayout
und java.awt.GridBagLayout
verwenden, so dass die Schaltelemente auf jeder Registerkarte auf eine andere Weise angeordnet werden. Da der Layout Manager java.awt.CardLayout
nicht automatisch ein Schaltelement zum Wechseln der Registerkarten anbietet, programmieren Sie zusätzlich eine entsprechende Möglichkeit.
Wird der Layout Manager java.awt.CardLayout
verwendet, so werden alle Schaltelemente, die mit add()
dem Container hinzugefügt werden, der sich des Layout Managers java.awt.CardLayout
bedient, als einzelne Registerkarten betrachtet. Um jeweils drei Schaltflächen vom Typ java.awt.Button
auf einer Registerkarte anzuordnen, erstellen Sie Objekte vom Typ java.awt.Panel
und fügen Sie die drei Schaltflächen diesen Objekten hinzu. Fügen Sie dann die Objekte vom Typ java.awt.Panel
dem Container hinzu, der den Layout Manager java.awt.CardLayout
verwendet. Bieten Sie außerdem dem Anwender eine Möglichkeit zum Wechseln der Registerkarten an, indem Sie beispielsweise vier weitere Schaltflächen vom Typ java.awt.Button
außerhalb des Registerkartensteuerelements erstellen.
Entwickeln Sie ein Java-Applet, dessen Oberfläche Sie mit dem Layout Manager java.awt.GridLayout
in vier Felder einteilen. Fügen Sie jedem der vier Felder ein Objekt vom Typ java.awt.Panel
hinzu und setzen Sie die Hintergrundfarbe der vier Panels auf unterschiedliche Werte. Wenn der Mauszeiger sich über den vier Panels befindet, soll er für jedes Panel geändert und neu gesetzt werden. Ändern Sie den Mauszeiger zum Beispiel in ein Fadenkreuz, eine Hand, eine Texteinfügemarke und eine Sanduhr.
Alle Klassen, die von java.awt.Component
abgeleitet sind - also auch java.awt.Panel
- ermöglichen über den Aufruf der Methode setCursor()
, einen Mauszeiger einzustellen, der automatisch angezeigt werden soll, wenn sich die Maus über der jeweiligen Komponente befindet. Rufen Sie diese Methode für Ihre vier Panels auf und geben Sie vier unterschiedliche Mauszeiger an, damit jedes Panel seinen eigenen Mauszeiger bekommt.
Entwickeln Sie ein Java-Applet, das den Layout Manager java.awt.BorderLayout
verwendet und zentriert ein einzeiliges Texteingabefeld vom Typ java.awt.TextField
anzeigt. Wenn der Anwender in das Eingabefeld "Nord", "Süd", "West", "Ost" oder "Zentrum" eingibt, soll das Eingabefeld im Layout Manager neu ausgerichtet werden. Verwenden Sie das Interface java.awt.event.TextListener
, um auf Tastatureingaben im Eingabefeld zu reagieren. Bei der Eingabe der fünf Begriffe zur Ausrichtung der Texteingabebox in der Applet-Oberfläche soll Groß- und Kleinschreibung nicht berücksichtigt werden.
Um das Texteingabefeld neu auszurichten, müssen Sie es zuerst mit remove()
aus der Applet-Oberfläche entfernen und dann erneut mit add()
hinzufügen. Beim Aufruf von add()
geben Sie die neue Ausrichtung des Texteingabefelds in der Applet-Oberfläche an. Rufen Sie danach die Methode validate()
auf, mit der Sie das Applet zwingen, die Oberfläche zu aktualisieren, damit mit remove()
gelöschte Schaltelemente tatsächlich verschwinden bzw. mit add()
neu hinzugefügte Schaltflächen sichtbar werden.
Copyright © 2001-2010 Boris Schäling