AWT -1- Abstract Windowing Toolkit Deligation Event Modell
Die Kommunikation zwischen dem Programm und dem Betriebssystem erfolgt
im Wesentlichen über das Versenden von Nachrichten.
Das Programm wird dabei über alle Arten von Ereignissen und
Zustandsänderungen vom Betriebssystem informiert.
Die Ereignissquelle (zB Button) sendet hierzu eine Nachricht an den
speziellen Empfänger (Listener),
der dann entsprechend reagieren kann.
Im Coding muss sich daher , dass sich der Ereignisempfänger
bei der Ereignisquelle registrieren muss.
Die Registrierung erfolgt mit speziellen Methoden, an die ein Objekt
übergeben wird, dass den entsprechenden Listener
(Empfänger) enthält.
//
Das Fenster
registriert mit
Methode addWindowListener
einen neuen WindowListener.
// als Parameter wird dieser Methode ein neues Objekt aus der Klasse WindowAdapter
übergeben. addWindowListener(new
WindowAdapter() {//1 // Der WindowAdapter enthält
nur die Methode windowClosing, der der Parameter "e" mitgegeben wird
public void windowClosing(WindowEvent e) {//2
System.exit(0);
}//2 }//1 );
import java.awt.*; import
java.awt.event.*;
public class
GUI_Uebung_S133 extends Frame {//1
//
Konstruktor
public GUI_Uebung_S133()
{//2 // Überschrift
setTitle("Übung S 133"); // WindowListener
// Das Fenster registriert mit Methode addWindowListener einen neuen
WindowListener.
// als Parameter wird dieser Methode ein neues Objekt aus der Klasse
WindowAdapter übergeben.
addWindowListener(new WindowAdapter()
{//3 // Der WindowAdapter enthält
nur die Methode windowClosing, der der Parameter "e" mitgegeben wird
public void windowClosing(WindowEvent e)
{//4
System.exit(0);
}//4
}//3
); //new WindowAdapter // einen Label mit mittigem Text
definieren,
Label Anzeige = new Label("LabelText", Label.CENTER);
// Label dem Fenster
hinzufügen
add(Anzeige); // noch einen zusätzlichen
Button zum Beenden
Button Ende = new Button("ich beende auch dieses Fenster"); // Fügt dem
Button einen ActionListener zu, der die Ereignisse abgreift, die // durch die
Schaltfläche ausgelöst werden.
Ende.addActionListener(new ActionListener()
{//3
public void actionPerformed(ActionEvent e)
{//4
System.exit(0);
}//4
}//3
);//ActionListener // Button
hinzufügen
add(Ende); // Groesse Fenster
setSize(300,80); // Fenster sichtbar machen
setVisible(true);
}//2 Konstruktor
//
Hauptprogramm
public static void main(String[] args)
{//2
new GUI_Uebung_S133();
}//2 }//1
Anonyme innere Klassen
Innerhalb der Funktion addWindowListener wird eine
anonyme Klasse, die keinen Namen hat, von der Basisklasse WindowAdapter erzeugt. addWindowListener(new WindowAdapter(evtl Parameter
für Konstruktor der Basisklasse)
{//3 // Die folgende Methode ist eine
Methode der Basisklasse WindowAdapter und wird überschrieben
public void windowClosing(WindowEvent e)
{//4
System.exit(0);
}//4
}//3
); //new WindowAdapter
Anonyme oder unbenannte (innere) Klassen
Im Bereich von EventListenern
und EventAdaptern braucht man
die dafür verwendeten inneren Klassen häufig nur, um genau
ein Objekt dieser Klasse zu erzeugen. Um dem Programmierer die Arbeit
abzunehmen, für einen solche Klasse einen Namen anzugeben, wurde
eine abgekürzte Klassendefinition innerhalb eines new-Operators
eingeführt, ohne Angabe
eines Klassennamens.
Der Compiler vergibt für die übersetzte anonyme Klasse einen
systematisch erzeugten Klassennamen der Form NameDerUmgebendenKlasse$n.
Man erzeugt ein Objekt einer anonymen Klasse mit einem new-Operator,
indem man eine Basisklasse oder
ein Interface angibt, gefolgt
von einem Klassenkörper: new BaseClassName ( evtl.
Parameter für Konstruktor von BaseClassName ) {//1
Klassenkörper ohne Konstruktoren }//1
oder new InterfaceName( ) {//1
Klassenkörper ohne Konstruktoren }//1
Anonyme Klassen sind also
a) entweder von einer bekannten Basisklasse abgeleitet oder
b) implementieren ein bekanntes Interface.
Im letzeren Fall wird die Klasse Object als Basisklasse genommen.
Anonyme Klassen können keine Konstruktoren haben. Parameter des
new-Operators gehen an den Konstruktor der angegebenden Basisklasse.
Explizite extends- oder implements-Klauseln sind nicht erlaubt.
Konkretes Beispiel (Klassenkörper der anonymen Klasse
hervorgehoben): class TheFrame extends Frame {
TheFrame( ) { // Konstruktor
addWindowListener( new WindowAdapter( ) {
void windowClosing( ) {
System.exit(0);
} }); }
...
}
Das Beispiel arbeitet mit einer von Klasse Frame abgeleiteten Klasse
TheFrame, weil die
Quelltextskizze so kurz und übersichtlich ist, und weil es
häufig aus anderen Gründen nötig ist,
Vererbung einzusetzen. Zum Registrieren von EventListenern allein ist
der Einsatz von Vererbung
nicht nötig, man könnte auch eine Instanz von Frame erzeugen
und bei Ihr Listener registrieren. Die
spezifische Verarbeitung von Events kann man also beim Modell der
Delegierung von Events über
spezifische Listener zu einer existierenden Component-Klasse
"hinzukonfigurieren".