Das Paket java.awt ( abstract windowing toolkit) dient zur Realisierung grafischer Benutzungsschnittstellen:
Das awt-Paket wurde für Java1.1 stark revidiert.
Vor allem: Ersetzen der nicht-objektorientierten
Ereignisbehandlung.
Entwicklung einer grafischen Benutzungsschnittstelle erfordert 4 Schritte:
Button quit = new Button("quit"):
myContainer.add(quit):
Ereignisse werden von Ereignisquellen erzeugt. Ein oder mehrere Listener melden sich an, um über die Ereignisse an einer Quelle informiert zu werden.
die Ereignisbehandlung wird an irgendein Objekt delegiert, das das
zum Ereignis passende Interface implementiert.
Zur Ereignisbehandlung brauchen wir folgendes
public class MyEvtHdl implements ActionListener { ...
quitknopf.addActionListener( new MyEvtHdl());
public void actionPerformed( ActionEvent e) { // irgendwie auf das // Ereignis reagieren
Beispiel: Ein piepsender Knopf
Hier ist der ActionListener selbst Besitzer des Knopfes. Das muß natürlich nicht so sein.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Beeper extends Applet implements ActionListener { Button button; public void init() { setLayout(new BorderLayout()); button = new Button("Click Me"); add("Center", button); button.addActionListener(this); } public void actionPerformed( ActionEvent e) { Toolkit.getDefaultToolkit().beep(); } }
Oft nutzt man die neuen inneren Klassen für die Eventbehandlung:
public class Beeper1 extends Applet { Button button; public void init() { setLayout(new BorderLayout()); button = new Button("Click Me"); add("Center", button); button.addActionListener( new BeepAction()); } class BeepAction implements ActionListener { public void actionPerformed( ActionEvent e) { Toolkit.getDefaultToolkit().beep(); } } }
Wenn nur ein Handler-Objekt benötigt wird: anonyme Klassen :
public class Beeper2 extends Applet { Button button; public void init() { setLayout(new BorderLayout()); button = new Button("Click Me"); add("Center", button); button.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e) { Toolkit.getDefaultToolkit(). beep(); } } ); } }
Nicht objektorientiert. Anwender macht Fallunterscheidung über Event-Typen und Event-Ziele:
public class Beeper3 extends Applet { // JDK 1.0 Event Handling Button button; public void init() { setLayout(new BorderLayout()); button = new Button("Click Me"); add("Center", button); } public boolean action(Event e, Object arg) { if (e.target.equals(button)) Toolkit.getDefaultToolkit().beep(); else return super.action(e,arg); return true; } }
Adapterklassen lösen das Problem, indem sie für alle Methoden
des Interfaces leere Default-Implementierungen bereitstellen.
Man erbt von einer Adapterklasse und überschreibt die benötigte
Eventhandling-Methode:
MyClass extends MouseAdapter { .... public void mouseClicked( MouseEvent e) { ... } } ... button.addMouseListener(new MyClass());
Für alle Eventarten mit mehr als einer Behandlungsmethode existiert eine Adapterklasse entsprechenden Namens.
Beispiel:
Listener: KeyListener
Adapter: KeyAdapter
Listener Interface | Methoden |
ActionListener | actionPerformed |
AdjustmentListener | adjustmentValueChanged |
ComponentListener | componentHidden |
componentMoved | |
componentResized | |
componentShown | |
ContainerListener | componentAdded |
componentRemoved | |
FocusListener | focusGained |
focusLost | |
ItemListener | itemStateChanged |
KeyListener | keyPressed |
keyReleased | |
keyTyped | |
MouseListener | mouseClicked |
mouseEntered | |
mouseExited | |
mousePressed | |
mouseReleased |
Listener Interface | Methoden |
MouseMotionListener | mouseDragged |
mouseMoved | |
TextListener | textValueChanged |
WindowListener | windowActivated |
windowClosed | |
windowClosing | |
windowDeactivated | |
windowDeiconified | |
windowIconified | |
windowOpened |
Unterklassen der Klasse Component
Diese Oberfläche
(Java-Quellcode)
enthält die meisten vordefinierten Komponenten des AWT:
Die Klasse Button stellt Schaltflächen mit Aufschrift zur Verfügung. Klicken erzeugt einen ActionEvent.
Button cancel = new Button("Geh weg"); this.add(cancel); // Event-Handling dafür ActionListener buttonlistener = new ActionListener() { public void actionPerformed( ActionEvent e) { // Behandle Ereignis ... } }; cancel.addActionListener(buttonlistener);
Freie rechteckige Fläche zum Zeichnen.
Wird auch zur Erzeugung eigener Grafik-Komponenten verwendet.
Zur Darstellung des Canvas:: paint-Methode überschreiben.
Grafische Schaltkomponente, die entweder ein- oder ausgeschaltet sein kann ( true oder false). Klicken schaltet zwischen den beiden Zuständen hin und her.
add(new Checkbox("one", true)); add(new Checkbox("two")); add(new Checkbox("three"));
Radioknöpfe (nur einer ist angeschaltet), können
mit der Klasse CheckboxGroup realisiert werden:
CheckboxGroup ckg = new CheckboxGroup(); add(new Checkbox("one", ckg, true)); add(new Checkbox("two", ckg)); add(new Checkbox("three", ckg));
Die Klasse Choice realisiert ein Pop-Up-Menu zur Auswahl. Die aktuell gültige Auswahl wird als Titel des Menüs angezeigt.
Choice ColorChooser = new Choice(); ColorChooser.add("while"); ColorChooser.add("If-then-else"); ColorChooser.add("switch");
Komponente, mit der man Read-Only-Text in einem Container plazieren kann.
add(new Label("Hi There!")); add(new Label("Another Label"));
Listen von Texteinträgen, aus denen ein oder mehrere ausgewählt werden können.
List lst = new List(3, false); lst.add("Apfel"); lst.add("Birne"); lst.add("Kirsche"); lst.add("Banane"); container.add(lst);
Der zweite Parameter des Konstruktors steuert, ob mehrere Einträge
auswählbar sind.
Eine TextArea-Komponente ist ein mehrzeiliger Bereich in dem Text angezeigt und/oder eingegeben werden kann.
Eine TextField-Komponente ist ein einzeiliger Bereich zur Texteingabe.
Beispiel:
// Import-Klauseln gelöscht public class TextDemo extends Applet implements ActionListener { TextField zeile; TextArea feld; public void init() { zeile = new TextField(20); feld = new TextArea(5, 20); feld.setEditable(false); add(zeile); add(feld); zeile.addActionListener(this); } public void actionPerformed( ActionEvent evt) { feld.append(zeile.getText() + "\n"); zeile.selectAll(); } }
Container sind Grafikkomponenten, die andere Komponenten aufnehmen können.
Zugefügte Komponenten (Methode add()), werden in einer Liste
gespeichert und von einem Layout Manager
angeordnet.
Solange es offen ist, blockiert es die Eingabe in andere Fenster.
Dialoge hängen von anderen Fenstern ab, sie werden
z.B. zerstört wenn das Grundfenster zerstört wird.
Top-Level-Fenster mit Titel und Rahmen. Kann Menüs haben. Jede Applikation braucht mindestens einen Frame.
public class AllComponents extends Frame implements ActionListener { public AllComponents(String title) { super(title); // Reaktion auf Fensterschließen this.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e) { System.exit(0); } } ); public static void main(String[] args) { Frame f = new AllComponents( "Erste AWT Demo"); f.pack(); f.show(); } }
konstruiert:
// Menü-Leiste mb = new MenuBar(); setMenuBar(mb); // Ein Menü m1 = new Menu("Datei"); mb.add(m1); // Menüeinträge schl = new MenuItem("Schließen"); m1.add(schl); // usw.
Menü-Aktionen lösen Action-Events aus:
// Eintrag mit Shortcut MenuItem open = new MenuItem("Öffne", new MenuShortcut( KeyEvent.VK_O)); open.setActionCommand("open"); open.addActionListener(this); .... public void actionPerformed( ActionEvent e) { String command = e.getActionCommand(); if (command.equals("open")) { ...
Nur Container, die die MenuContainer-Schnittstelle
implementieren können Menüs haben (z.B. ein Frame).
Jeder Container hat einen Standard Layout Manager, der dafür zuständig ist, die enthaltenen Komponenten anzuordnen. Dieser voreingestellte Layout Manager kann durch einen anderen ersetzt werden.
Das AWT bietet:
Beispiel
Zuordnung eines Layout-Managers zu einem Container:
meinContainer.setLayout(new CardLayout());
Anordnung der Komponenten an den vier Rändern und in der Mitte.
import java.awt.*; import java.applet.Applet; public class ButtonDir extends Applet { public void init() { setLayout(new BorderLayout()); add("North", new Button("North")); add("South", new Button("South")); add("East", new Button("East")); add("West", new Button("West")); add("Center", new Button("Center")); } }
Überlagerung der Komponenten.
cards = new Panel(); cards.setLayout(new CardLayout()); ...// Erzeuge Panel p1 mit Knöpfen ...// Erzeuge Panel p1 mit Textfeld cards.add("Panel with Buttons", p1); cards.add("Panel with TextField", p2);
Die Strings dienen zur Identifikation der Karten.
Das Umschalten zwischen sich verdeckenden Karten muß man
ausprogrammieren, z.B.:
(CardLayout)cards.getLayout()). show(cards,"Panel with TextField");
Komponenten der Reihe nach angeordnet.
setLayout(new FlowLayout()); setFont(new Font("Helvetica", Font.PLAIN, 14)); add(new Button("Button 1")); add(new Button("2")); add(new Button("Button 3")); add(new Button("Long-Named Button 4")); add(new Button("Button 5"));
Durch Konstruktorargument kann angegeben werden, ob die Komponenten
innerhalb einer Zeile zentriert (Default), rechts- oder linksbündig
angeordnet werden.
Komponenten in einem Matrix-Raster.
// Beliebigviele Reihen, 2 Spalten setLayout(new GridLayout(0,2)); add(new Button("Button 1")); add(new Button("2")); add(new Button("Button 3")); add(new Button("Long-Named Button 4")); add(new Button("Button 5"));
Komponenten in einem flexiblen Matrix-Raster. Mächtigster aber auch kompliziertester Layout Manager:
Das Layout wird durch GridBagConstraints spezifiziert:
GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setLayout(gridbag); //...Nach Setzen der Attribute von c: add(irgendeineKomponente, c);
Die wichtigsten Attribute von GridBagConstraints sind:
Die Knöpfe 8 und 9 der Oberfläche (Seite )
wurden z.B. wie folgt erzeugt:
GridBagLayout griba = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setLayout(griba); c.fill = GridBagConstraints.BOTH; c.gridwidth = 1; c.gridheight = 2; c.weighty = 1.0; add(new Button("Button8"), c); c.weighty = 0.0; c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = 1; add(new Button("Button9"), c);