diff options
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100182.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100182.html | 943 |
1 files changed, 943 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100182.html b/Master/Reference Architectures and Patterns/hjp5/html/k100182.html new file mode 100644 index 0000000..f8ab2c3 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100182.html @@ -0,0 +1,943 @@ +<html>
+<head>
+<title>
+Handbuch der Java-Programmierung, 5. Auflage
+</title>
+</head>
+<body>
+<a name="startofbody"></a>
+<script language="JavaScript" src="hjp4lib.js">
+</script>
+<script language="JavaScript">
+installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100180.html;106,k100181.html;107,k100183.html;108,k100184.html");
+</script>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100180.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100181.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100183.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100184.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">Kapitel 28 - Event-Handling
+</table>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel2id028002"></a>
+<h2>28.2 Entwurfsmuster für den Nachrichtenverkehr </h2>
+<hr>
+<ul>
+<li><a href="k100182.html#sectlevel2id028002">28.2 Entwurfsmuster für den Nachrichtenverkehr</a>
+<ul>
+<li><a href="k100182.html#sectlevel3id028002001">28.2.1 Variante 1: Implementierung eines EventListener-Interfaces</a>
+<li><a href="k100182.html#lokaleanonymeeventhandler">28.2.2 Variante 2: Lokale und anonyme Klassen</a>
+<ul>
+<li><a href="k100182.html#sectlevel4id028002002001">Lokale Klassen</a>
+<li><a href="k100182.html#sectlevel4id028002002002">Anonyme Klassen</a>
+</ul>
+<li><a href="k100182.html#mediatorinjava">28.2.3 Variante 3: Trennung von GUI- und Anwendungscode</a>
+<li><a href="k100182.html#sectlevel3id028002004">28.2.4 Variante 4: Überlagern der Event-Handler in den Komponenten</a>
+<li><a href="k100182.html#sectlevel3id028002005">28.2.5 Ausblick</a>
+</ul>
+</ul>
+<hr>
+
+<p>
+Wir wollen uns in diesem Abschnitt damit beschäftigen, die oben
+erwähnten Entwurfsmuster für die Abwicklung des Nachrichtenverkehrs
+in Java-Programmen vorzustellen. Wie bereits erwähnt, hat jedes
+dieser Verfahren seine ganz spezifischen Vor- und Nachteile und ist
+für verschiedene Programmieraufgaben unterschiedlich gut geeignet.
+
+<p>
+Als Basis für unsere Experimente wollen wir ein einfaches Programm
+schreiben, das die folgenden Anforderungen erfüllt:
+<ul>
+<li>Nach dem Start soll das Programm ein Fenster mit dem Titel »Nachrichtentransfer«
+auf dem Bildschirm anzeigen.
+<li>Das Fenster soll einen grauen Hintergrund haben und in der Client-Area
+die Meldung »Zum Beenden bitte ESC drücken ...« anzeigen.
+<li>Nach Drücken der Taste <font color="#007700"><tt>[ESC]</tt></font>
+soll das Fenster geschlossen und das Programm beendet werden. Andere
+Tastendrücke, Mausklicks oder ähnliche Ereignisse werden
+ignoriert.
+</ul>
+
+<p>
+Basis der Programme ist das folgende Listing:
+<a name="listingid028001"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing2801.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.awt.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.awt.event.*;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2801
+<font color="#555555">007 </font><font color="#0000AA">extends</font> Frame
+<font color="#555555">008 </font>{
+<font color="#555555">009 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">010 </font> {
+<font color="#555555">011 </font> Listing2801 wnd = <font color="#0000AA">new</font> Listing2801();
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font>
+<font color="#555555">014 </font> <font color="#0000AA">public</font> Listing2801()
+<font color="#555555">015 </font> {
+<font color="#555555">016 </font> <font color="#006699">super</font>(<font color="#0000FF">"Nachrichtentransfer"</font>);
+<font color="#555555">017 </font> setBackground(Color.lightGray);
+<font color="#555555">018 </font> setSize(300,200);
+<font color="#555555">019 </font> setLocation(200,100);
+<font color="#555555">020 </font> setVisible(<font color="#006699">true</font>);
+<font color="#555555">021 </font> }
+<font color="#555555">022 </font>
+<font color="#555555">023 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> paint(Graphics g)
+<font color="#555555">024 </font> {
+<font color="#555555">025 </font> g.setFont(<font color="#0000AA">new</font> Font(<font color="#0000FF">"Serif"</font>,Font.PLAIN,18));
+<font color="#555555">026 </font> g.drawString(<font color="#0000FF">"Zum Beenden bitte ESC drücken..."</font>,10,50);
+<font color="#555555">027 </font> }
+<font color="#555555">028 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing2801.java"><font color="#000055" size=-1>Listing2801.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 28.1: Basisprogramm für den Nachrichtentransfer</i></p>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Das Programm erfüllt die ersten der obengenannten Anforderungen,
+ist aber mangels Event-Handler noch nicht in der Lage, per <font color="#007700"><tt>[ESC]</tt></font>
+beendet zu werden. Um die Nachfolgeversionen vorzubereiten, haben
+wir bereits die Anweisung <font color="#000077"><tt>import java.awt.event.*</tt></font>
+eingefügt.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Die Ausgabe des Programms ist:
+<p>
+<a name="imageid028003"></a>
+<img src="images/NachrVerkehr.gif">
+<p>
+
+<p><i>
+Abbildung 28.3: Das Programm für den Nachrichtentransfer</i></p>
+
+
+<!-- Section -->
+<a name="sectlevel3id028002001"></a>
+<h3>28.2.1 Variante 1: Implementierung eines EventListener-Interfaces
+</h3>
+
+<p>
+Bei der ersten Variante gibt es nur eine einzige Klasse, <font color="#000077"><tt>Listing2802</tt></font>.
+Sie ist einerseits eine Ableitung der Klasse <a href="index_f.html#ixb101144"><font color=#000080><tt>Frame</tt></font></a>,
+um ein Fenster auf dem Bildschirm darzustellen und zu beschriften.
+Andererseits implementiert sie das Interface <a name="ixa101914"><a href="index_k.html#ixb101437"><font color=#000080><tt>KeyListener</tt></font></a></a>,
+das die Methoden <a name="ixa101915"><a href="index_k.html#ixb101438"><font color=#000080><tt>keyPressed</tt></font></a></a>,
+<a name="ixa101916"><a href="index_k.html#ixb101439"><font color=#000080><tt>keyReleased</tt></font></a></a>
+und <a name="ixa101917"><a href="index_k.html#ixb101440"><font color=#000080><tt>keyTyped</tt></font></a></a>
+definiert. Der eigentliche Code zur Reaktion auf die Taste <font color="#007700"><tt>[ESC]</tt></font>
+steckt in der Methode <a href="index_k.html#ixb101438"><font color=#000080><tt>keyPressed</tt></font></a>,
+die immer dann aufgerufen wird, wenn eine Taste gedrückt wurde.
+Mit der Methode <a name="ixa101918"><a href="index_g.html#ixb101491"><font color=#000080><tt>getKeyCode</tt></font></a></a>
+der Klasse <a name="ixa101919"><a href="index_k.html#ixb101412"><font color=#000080><tt>KeyEvent</tt></font></a></a>
+wird auf den Code der gedrückten Taste zugegriffen und dieser
+mit der symbolischen Konstante <a name="ixa101920"><a href="index_v.html#ixb101492"><font color=#000080><tt>VK_ESCAPE</tt></font></a></a>
+verglichen. Stimmen beide überein, wurde <font color="#007700"><tt>[ESC]</tt></font>
+gedrückt, und das Programm kann beendet werden.
+<a name="variante1"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing2802.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.awt.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.awt.event.*;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2802
+<font color="#555555">007 </font><font color="#0000AA">extends</font> Frame
+<font color="#555555">008 </font><font color="#0000AA">implements</font> KeyListener
+<font color="#555555">009 </font>{
+<font color="#555555">010 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">011 </font> {
+<font color="#555555">012 </font> Listing2802 wnd = <font color="#0000AA">new</font> Listing2802();
+<font color="#555555">013 </font> }
+<font color="#555555">014 </font>
+<font color="#555555">015 </font> <font color="#0000AA">public</font> Listing2802()
+<font color="#555555">016 </font> {
+<font color="#555555">017 </font> <font color="#006699">super</font>(<font color="#0000FF">"Nachrichtentransfer"</font>);
+<font color="#555555">018 </font> setBackground(Color.lightGray);
+<font color="#555555">019 </font> setSize(300,200);
+<font color="#555555">020 </font> setLocation(200,100);
+<font color="#555555">021 </font> setVisible(<font color="#006699">true</font>);
+<font color="#555555">022 </font> addKeyListener(<font color="#006699">this</font>);
+<font color="#555555">023 </font> }
+<font color="#555555">024 </font>
+<font color="#555555">025 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> paint(Graphics g)
+<font color="#555555">026 </font> {
+<font color="#555555">027 </font> g.setFont(<font color="#0000AA">new</font> Font(<font color="#0000FF">"Serif"</font>,Font.PLAIN,18));
+<font color="#555555">028 </font> g.drawString(<font color="#0000FF">"Zum Beenden bitte ESC drücken..."</font>,10,50);
+<font color="#555555">029 </font> }
+<font color="#555555">030 </font>
+<font color="#555555">031 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyPressed(KeyEvent event)
+<font color="#555555">032 </font> {
+<font color="#555555">033 </font> <font color="#0000AA">if</font> (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
+<font color="#555555">034 </font> setVisible(<font color="#006699">false</font>);
+<font color="#555555">035 </font> dispose();
+<font color="#555555">036 </font> System.exit(0);
+<font color="#555555">037 </font> }
+<font color="#555555">038 </font> }
+<font color="#555555">039 </font>
+<font color="#555555">040 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyReleased(KeyEvent event)
+<font color="#555555">041 </font> {
+<font color="#555555">042 </font> }
+<font color="#555555">043 </font>
+<font color="#555555">044 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyTyped(KeyEvent event)
+<font color="#555555">045 </font> {
+<font color="#555555">046 </font> }
+<font color="#555555">047 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing2802.java"><font color="#000055" size=-1>Listing2802.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 28.2: Implementieren eines Listener-Interfaces</i></p>
+
+<p>
+Die Verbindung zwischen der Ereignisquelle (in diesem Fall der Fensterklasse
+<font color="#000077"><tt>Listing2802</tt></font>) und dem Ereignisempfänger
+(ebenfalls die Klasse <font color="#000077"><tt>Listing2802</tt></font>)
+erfolgt über den Aufruf der Methode <a name="ixa101921"><a href="index_a.html#ixb101362"><font color=#000080><tt>addKeyListener</tt></font></a></a>
+der Klasse <a href="index_f.html#ixb101144"><font color=#000080><tt>Frame</tt></font></a>.
+Alle Tastaturereignisse werden dadurch an die Fensterklasse selbst
+weitergeleitet und führen zum Aufruf der Methoden <a href="index_k.html#ixb101438"><font color=#000080><tt>keyPressed</tt></font></a>,
+<a href="index_k.html#ixb101439"><font color=#000080><tt>keyReleased</tt></font></a>
+oder <a href="index_k.html#ixb101440"><font color=#000080><tt>keyTyped</tt></font></a>
+des Interfaces <a href="index_k.html#ixb101437"><font color=#000080><tt>KeyListener</tt></font></a>.
+Diese Implementierung ist sehr naheliegend, denn sie ist einfach zu
+implementieren und erfordert keine weiteren Klassen. Nachteilig ist
+dabei allerdings:
+<ul>
+<li>Es besteht keine Trennung zwischen GUI-Code und Applikationslogik.
+Dies kann große Programme unübersichtlich und schwer wartbar
+machen.
+<li>Für jeden Ereignistyp muss eine passende Listener-Klasse
+registriert werden. Da viele der <a href="index_e.html#ixb101396"><font color=#000080><tt>EventListener</tt></font></a>-Interfaces
+mehr als eine Methode definieren, werden dadurch schnell viele leere
+Methodenrümpfe in der Fensterklasse zu finden sein. In diesem
+Beispiel sind es schon <a href="index_k.html#ixb101439"><font color=#000080><tt>keyReleased</tt></font></a>
+und <a href="index_k.html#ixb101440"><font color=#000080><tt>keyTyped</tt></font></a>,
+bei zusätzlichen Interfaces würden schnell weitere hinzukommen.
+</ul>
+
+<p>
+Es bleibt festzuhalten, dass diese Technik bestenfalls für kleine
+Programme geeignet ist, die nur begrenzt erweitert werden müssen.
+Durch die Vielzahl leerer Methodenrümpfe können aber auch
+kleine Programme schnell unübersichtlich werden.
+
+<!-- Section -->
+
+<a name="lokaleanonymeeventhandler"></a>
+<h3>28.2.2 Variante 2: Lokale und anonyme Klassen </h3>
+
+<p>
+Die zweite Alternative bietet eine bessere Lösung. Sie basiert
+auf der Verwendung <i>lokaler</i> bzw. <i>anonymer</i> Klassen und
+kommt ohne die Nachteile der vorigen Version aus. Sie ist das in der
+Dokumentation des JDK empfohlene Entwurfsmuster für das Event-Handling
+in kleinen Programmen oder bei Komponenten mit einfacher Nachrichtenstruktur.
+Vor ihrem Einsatz sollte man allerdings das Prinzip lokaler und anonymer
+Klassen kennenlernen, das mit dem JDK 1.1 in Java eingeführt
+und in <a href="k100065.html#lokaleanonymeklassen">Abschnitt 10.1</a>
+vorgestellt wurde. Wer diesen Abschnitt noch nicht gelesen hat, sollte
+das jetzt nachholen.
+
+<!-- Section -->
+
+<a name="sectlevel4id028002002001"></a>
+<h4>Lokale Klassen<a name="ixa101922"></a> </h4>
+
+<p>
+Die Anwendung lokaler Klassen für die Ereignisbehandlung besteht
+darin, mit ihrer Hilfe die benötigten <a href="index_e.html#ixb101396"><font color=#000080><tt>EventListener</tt></font></a>
+zu implementieren. Dazu wird in dem GUI-Objekt, das einen Event-Handler
+benötigt, eine lokale Klasse definiert und aus einer passenden
+<i>Adapterklasse</i> abgeleitet. Nun braucht nicht mehr das gesamte
+Interface implementiert zu werden (denn die Methodenrümpfe werden
+ja aus der Adapterklasse geerbt), sondern lediglich die tatsächlich
+benötigten Methoden. Da die lokale Klasse zudem auf die Membervariablen
+und Methoden der Klasse zugreifen kann, in der sie definiert wurde,
+lassen sich auf diese Weise sehr schnell die benötigten Ereignisempfänger
+zusammenbauen.
+
+<p>
+Das folgende Beispiel definiert eine lokale Klasse <font color="#000077"><tt>MyKeyListener</tt></font>,
+die aus <a name="ixa101923"><a href="index_k.html#ixb101424"><font color=#000080><tt>KeyAdapter</tt></font></a></a>
+abgeleitet wurde und auf diese Weise das <a name="ixa101924"><a href="index_k.html#ixb101437"><font color=#000080><tt>KeyListener</tt></font></a></a>-Interface
+implementiert. Sie überlagert lediglich die Methode <a href="index_k.html#ixb101438"><font color=#000080><tt>keyPressed</tt></font></a>,
+um auf das Drücken einer Taste zu reagieren. Als lokale Klasse
+hat sie außerdem Zugriff auf die Methoden der umgebenden Klasse
+und kann somit durch Aufruf von <a href="index_s.html#ixb101147"><font color=#000080><tt>setVisible</tt></font></a>
+und <a href="index_d.html#ixb101296"><font color=#000080><tt>dispose</tt></font></a>
+das Fenster, in dem sie als Ereignisempfänger registriert wurde,
+schließen. Die Registrierung der lokalen Klasse erfolgt durch
+Aufruf von <a href="index_a.html#ixb101362"><font color=#000080><tt>addKeyListener</tt></font></a>,
+bei dem gleichzeitig eine Instanz der lokalen Klasse erzeugt wird.
+Als lokale Klasse ist <font color="#000077"><tt>MyKeyListener</tt></font>
+überall innerhalb von <font color="#000077"><tt>Listing2803</tt></font>
+sichtbar und kann an beliebiger Stelle instanziert werden.
+<a name="variante2a"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing2803.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.awt.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.awt.event.*;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2803
+<font color="#555555">007 </font><font color="#0000AA">extends</font> Frame
+<font color="#555555">008 </font>{
+<font color="#555555">009 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">010 </font> {
+<font color="#555555">011 </font> Listing2803 wnd = <font color="#0000AA">new</font> Listing2803();
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font>
+<font color="#555555">014 </font> <font color="#0000AA">public</font> Listing2803()
+<font color="#555555">015 </font> {
+<font color="#555555">016 </font> <font color="#006699">super</font>(<font color="#0000FF">"Nachrichtentransfer"</font>);
+<font color="#555555">017 </font> setBackground(Color.lightGray);
+<font color="#555555">018 </font> setSize(300,200);
+<font color="#555555">019 </font> setLocation(200,100);
+<font color="#555555">020 </font> setVisible(<font color="#006699">true</font>);
+<font color="#555555">021 </font> addKeyListener(<font color="#0000AA">new</font> MyKeyListener());
+<font color="#555555">022 </font> }
+<font color="#555555">023 </font>
+<font color="#555555">024 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> paint(Graphics g)
+<font color="#555555">025 </font> {
+<font color="#555555">026 </font> g.setFont(<font color="#0000AA">new</font> Font(<font color="#0000FF">"Serif"</font>,Font.PLAIN,18));
+<font color="#555555">027 </font> g.drawString(<font color="#0000FF">"Zum Beenden bitte ESC drücken..."</font>,10,50);
+<font color="#555555">028 </font> }
+<font color="#555555">029 </font>
+<font color="#555555">030 </font> <font color="#0000AA">class</font> MyKeyListener
+<font color="#555555">031 </font> <font color="#0000AA">extends</font> KeyAdapter
+<font color="#555555">032 </font> {
+<font color="#555555">033 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyPressed(KeyEvent event)
+<font color="#555555">034 </font> {
+<font color="#555555">035 </font> <font color="#0000AA">if</font> (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
+<font color="#555555">036 </font> setVisible(<font color="#006699">false</font>);
+<font color="#555555">037 </font> dispose();
+<font color="#555555">038 </font> System.exit(0);
+<font color="#555555">039 </font> }
+<font color="#555555">040 </font> }
+<font color="#555555">041 </font> }
+<font color="#555555">042 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing2803.java"><font color="#000055" size=-1>Listing2803.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 28.3: Verwendung lokaler Klassen</i></p>
+
+<p>
+Der Vorteil dieser Vorgehensweise ist offensichtlich: es werden keine
+unnützen Methodenrümpfe erzeugt, aber trotzdem verbleibt
+der Ereignisempfängercode wie im vorigen Beispiel innerhalb der
+Ereignisquelle. Dieses Verfahren ist also immer dann gut geeignet,
+wenn es von der Architektur oder der Komplexität der Ereignisbehandlung
+her sinnvoll ist, Quelle und Empfänger zusammenzufassen.
+
+<!-- Section -->
+
+<a name="sectlevel4id028002002002"></a>
+<h4>Anonyme Klassen<a name="ixa101925"></a> </h4>
+
+<p>
+Das folgende Beispiel ist eine leichte Variation des vorigen. Es zeigt
+die Verwendung einer anonymen Klasse, die aus <a name="ixa101926"><a href="index_k.html#ixb101424"><font color=#000080><tt>KeyAdapter</tt></font></a></a>
+abgeleitet wurde, als Ereignisempfänger. Zum Instanzierungszeitpunkt
+erfolgt die Definition der überlagernden Methode <a name="ixa101927"><a href="index_k.html#ixb101438"><font color=#000080><tt>keyPressed</tt></font></a></a>,
+in der der Code zur Reaktion auf das Drücken der Taste <font color="#007700"><tt>[ESC]</tt></font>
+untergebracht wird.
+<a name="listingid028004"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing2804.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.awt.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.awt.event.*;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2804
+<font color="#555555">007 </font><font color="#0000AA">extends</font> Frame
+<font color="#555555">008 </font>{
+<font color="#555555">009 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">010 </font> {
+<font color="#555555">011 </font> Listing2804 wnd = <font color="#0000AA">new</font> Listing2804();
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font>
+<font color="#555555">014 </font> <font color="#0000AA">public</font> Listing2804()
+<font color="#555555">015 </font> {
+<font color="#555555">016 </font> <font color="#006699">super</font>(<font color="#0000FF">"Nachrichtentransfer"</font>);
+<font color="#555555">017 </font> setBackground(Color.lightGray);
+<font color="#555555">018 </font> setSize(300,200);
+<font color="#555555">019 </font> setLocation(200,100);
+<font color="#555555">020 </font> setVisible(<font color="#006699">true</font>);
+<font color="#555555">021 </font> addKeyListener(
+<font color="#555555">022 </font> <font color="#0000AA">new</font> KeyAdapter() {
+<font color="#555555">023 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyPressed(KeyEvent event)
+<font color="#555555">024 </font> {
+<font color="#555555">025 </font> <font color="#0000AA">if</font> (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
+<font color="#555555">026 </font> setVisible(<font color="#006699">false</font>);
+<font color="#555555">027 </font> dispose();
+<font color="#555555">028 </font> System.exit(0);
+<font color="#555555">029 </font> }
+<font color="#555555">030 </font> }
+<font color="#555555">031 </font> }
+<font color="#555555">032 </font> );
+<font color="#555555">033 </font> }
+<font color="#555555">034 </font>
+<font color="#555555">035 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> paint(Graphics g)
+<font color="#555555">036 </font> {
+<font color="#555555">037 </font> g.setFont(<font color="#0000AA">new</font> Font(<font color="#0000FF">"Serif"</font>,Font.PLAIN,18));
+<font color="#555555">038 </font> g.drawString(<font color="#0000FF">"Zum Beenden bitte ESC drücken..."</font>,10,50);
+<font color="#555555">039 </font> }
+<font color="#555555">040 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing2804.java"><font color="#000055" size=-1>Listing2804.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 28.4: Verwendung einer anonymen Klasse als Ereignishandler</i></p>
+
+<p>
+Vorteilhaft bei dieser Vorgehensweise ist der verminderte Aufwand,
+denn es muss keine separate Klassendefinition angelegt werden. Statt
+dessen werden die wenigen Codezeilen, die zur Anpassung der Adapterklasse
+erforderlich sind, dort eingefügt, wo die Klasse instanziert
+wird, nämlich beim Registrieren des Nachrichtenempfängers.
+Anonyme Klassen haben einen ähnlichen Einsatzbereich wie lokale,
+empfehlen sich aber vor allem, wenn sehr wenig Code für den Ereignisempfänger
+benötigt wird. Bei aufwändigeren Ereignisempfängern
+ist die explizite Definition einer benannten Klasse dagegen vorzuziehen.
+
+
+<!-- Section -->
+<a name="mediatorinjava"></a>
+<h3>28.2.3 Variante 3: Trennung von GUI- und Anwendungscode </h3>
+
+<p>
+Wir hatten am Anfang darauf hingewiesen, dass in größeren
+Programmen eine Trennung zwischen Programmcode, der für die Oberfläche
+zuständig ist, und solchem, der für die Anwendungslogik
+zuständig ist, wünschenswert wäre. Dadurch wird eine
+bessere Modularisierung des Programms erreicht, und der Austausch
+oder die Erweiterung von Teilen des Programms wird erleichtert.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Das Delegation Event Model wurde auch mit dem Designziel entworfen,
+eine solche Trennung zu ermöglichen bzw. zu erleichtern. Der
+Grundgedanke dabei war es, auch Nicht-Komponenten die Reaktion auf
+GUI-Events zu ermöglichen. Dies wurde dadurch erreicht, dass
+jede Art von Objekt als Ereignisempfänger registriert werden
+kann, solange es die erforderlichen Listener-Interfaces implementiert.
+Damit ist es möglich, die Anwendungslogik vollkommen von der
+grafischen Oberfläche abzulösen und in Klassen zu verlagern,
+die eigens für diesen Zweck entworfen wurden.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Das nachfolgende Beispiel zeigt diese Vorgehensweise, indem es unser
+Beispielprogramm in die drei Klassen <font color="#000077"><tt>Listing2805</tt></font>,
+<font color="#000077"><tt>MainFrameCommand</tt></font> und <font color="#000077"><tt>MainFrameGUI</tt></font>
+aufteilt. <font color="#000077"><tt>Listing2805</tt></font> enthält
+nur noch die <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>-Methode
+und dient lediglich dazu, die anderen beiden Klassen zu instanzieren.
+<font color="#000077"><tt>MainFrameGUI</tt></font> realisiert die
+GUI-Funktionalität und stellt das Fenster auf dem Bildschirm
+dar. <font color="#000077"><tt>MainFrameCommand</tt></font> spielt
+die Rolle des Kommandointerpreters, der immer dann aufgerufen wird,
+wenn im Fenster ein Tastaturereignis aufgetreten ist.
+
+<p>
+Die Verbindung zwischen beiden Klassen erfolgt durch Aufruf der Methode
+<a href="index_a.html#ixb101362"><font color=#000080><tt>addKeyListener</tt></font></a>
+in <font color="#000077"><tt>MainFrameGUI</tt></font>, an die das
+an den Konstruktor übergebene <font color="#000077"><tt>MainFrameCommand</tt></font>-Objekt
+weitergereicht wird. Dazu ist es erforderlich, dass das Hauptprogramm
+den Ereignisempfänger <font color="#000077"><tt>cmd</tt></font>
+zuerst instanziert, um ihn bei der Instanzierung des GUI-Objekts <font color="#000077"><tt>gui</tt></font>
+übergeben zu können.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#0099CC"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=1></td>
+<td width=1 align=left valign=top bgcolor="#0099CC"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Umgekehrt benötigt natürlich auch das Kommando-Objekt Kenntnis
+über das GUI-Objekt, denn es soll ja das zugeordnete Fenster
+schließen und das Programm beenden. Der scheinbare Instanzierungskonflikt
+durch diese zirkuläre Beziehung ist aber in Wirklichkeit gar
+keiner, denn bei jedem Aufruf einer der Methoden von <font color="#000077"><tt>MainFrameCommand</tt></font>
+wird an das <a href="index_k.html#ixb101412"><font color=#000080><tt>KeyEvent</tt></font></a>-Objekt
+der Auslöser der Nachricht übergeben, und das ist in diesem
+Fall stets das <font color="#000077"><tt>MainFrameGUI</tt></font>-Objekt
+<font color="#000077"><tt>gui</tt></font>. So kann innerhalb des Kommando-Objekts
+auf alle öffentlichen Methoden des GUI-Objekts zugegriffen werden.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#0099CC">
+<tr>
+<td><font color="#FFFFFF"> Tipp </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#0099CC"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+<a name="variante3"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing2805.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.awt.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.awt.event.*;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2805
+<font color="#555555">007 </font>{
+<font color="#555555">008 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">009 </font> {
+<font color="#555555">010 </font> MainFrameCommand cmd = <font color="#0000AA">new</font> MainFrameCommand();
+<font color="#555555">011 </font> MainFrameGUI gui = <font color="#0000AA">new</font> MainFrameGUI(cmd);
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font>}
+<font color="#555555">014 </font>
+<font color="#555555">015 </font><font color="#0000AA">class</font> MainFrameGUI
+<font color="#555555">016 </font><font color="#0000AA">extends</font> Frame
+<font color="#555555">017 </font>{
+<font color="#555555">018 </font> <font color="#0000AA">public</font> MainFrameGUI(KeyListener cmd)
+<font color="#555555">019 </font> {
+<font color="#555555">020 </font> <font color="#006699">super</font>(<font color="#0000FF">"Nachrichtentransfer"</font>);
+<font color="#555555">021 </font> setBackground(Color.lightGray);
+<font color="#555555">022 </font> setSize(300,200);
+<font color="#555555">023 </font> setLocation(200,100);
+<font color="#555555">024 </font> setVisible(<font color="#006699">true</font>);
+<font color="#555555">025 </font> addKeyListener(cmd);
+<font color="#555555">026 </font> }
+<font color="#555555">027 </font>
+<font color="#555555">028 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> paint(Graphics g)
+<font color="#555555">029 </font> {
+<font color="#555555">030 </font> g.setFont(<font color="#0000AA">new</font> Font(<font color="#0000FF">"Serif"</font>,Font.PLAIN,18));
+<font color="#555555">031 </font> g.drawString(<font color="#0000FF">"Zum Beenden bitte ESC drücken..."</font>,10,50);
+<font color="#555555">032 </font> }
+<font color="#555555">033 </font>}
+<font color="#555555">034 </font>
+<font color="#555555">035 </font><font color="#0000AA">class</font> MainFrameCommand
+<font color="#555555">036 </font><font color="#0000AA">implements</font> KeyListener
+<font color="#555555">037 </font>{
+<font color="#555555">038 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyPressed(KeyEvent event)
+<font color="#555555">039 </font> {
+<font color="#555555">040 </font> Frame source = (Frame)event.getSource();
+<font color="#555555">041 </font> <font color="#0000AA">if</font> (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
+<font color="#555555">042 </font> source.setVisible(<font color="#006699">false</font>);
+<font color="#555555">043 </font> source.dispose();
+<font color="#555555">044 </font> System.exit(0);
+<font color="#555555">045 </font> }
+<font color="#555555">046 </font> }
+<font color="#555555">047 </font>
+<font color="#555555">048 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyReleased(KeyEvent event)
+<font color="#555555">049 </font> {
+<font color="#555555">050 </font> }
+<font color="#555555">051 </font>
+<font color="#555555">052 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> keyTyped(KeyEvent event)
+<font color="#555555">053 </font> {
+<font color="#555555">054 </font> }
+<font color="#555555">055 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing2805.java"><font color="#000055" size=-1>Listing2805.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 28.5: Trennung von GUI- und Anwendungslogik</i></p>
+
+<p>
+Diese Designvariante ist vorwiegend für größere Programme
+geeignet, bei denen eine Trennung von Programmlogik und Oberfläche
+sinnvoll ist. Für sehr kleine Programme oder solche, die wenig
+Ereigniscode haben, sollte eher eine der vorherigen Varianten angewendet
+werden, wenn diese zu aufwändig ist. Sie entspricht in groben
+Zügen dem <a name="ixa101928"><i>Mediator-Pattern</i></a>, das
+in »Design-Patterns« von Gamma et al. beschrieben wird.<a name="ixa101929"></a>
+
+<p>
+Natürlich erhebt das vorliegende Beispielprogramm nicht den Anspruch,
+unverändert in ein sehr großes Programm übernommen
+zu werden. Es soll lediglich die Möglichkeit der Trennung von
+Programmlogik und Oberfläche in einem großen Programm mit
+Hilfe der durch das Event-Handling des JDK 1.1 vorgegebenen Möglichkeiten
+aufzeigen. Eine sinnvolle Erweiterung dieses Konzepts könnte
+darin bestehen, weitere Modularisierungen vorzunehmen (z.B. analog
+dem <a name="ixa101930"><i>MVC</i></a>-Konzept von Smalltalk, bei
+dem GUI-Anwendungen in <i>Model</i>-, <i>View</i>- und <i>Controller</i>-Layer
+aufgesplittet werden, oder auch durch Abtrennen spezialisierter Kommandoklassen).
+Empfehlenswert ist in diesem Zusammenhang die Lektüre der JDK-Dokumentation,
+die ein ähnliches Beispiel in leicht veränderter Form enthält.
+
+
+<!-- Section -->
+<a name="sectlevel3id028002004"></a>
+<h3>28.2.4 Variante 4: Überlagern der Event-Handler in den Komponenten
+</h3>
+
+<p>
+Als letzte Möglichkeit, auf Nachrichten zu reagieren, soll das
+Überlagern der Event-Handler in den Ereignisquellen selbst aufgezeigt
+werden. Jede Ereignisquelle besitzt eine Reihe von Methoden, die für
+das Aufbereiten und Verteilen der Nachrichten zuständig sind.
+Soll eine Nachricht weitergereicht werden, so wird dazu zunächst
+innerhalb der Nachrichtenquelle die Methode <a name="ixa101931"><a href="index_p.html#ixb101497"><font color=#000080><tt>processEvent</tt></font></a></a>
+aufgerufen. Diese verteilt die Nachricht anhand ihres Typs an spezialisierte
+Methoden, deren Name sich nach dem Typ der zugehörigen Ereignisklasse
+richtet. So ist beispielsweise die Methode <a name="ixa101932"><a href="index_p.html#ixb101498"><font color=#000080><tt>processActionEvent</tt></font></a></a>
+für das Handling von Action-Events und <a name="ixa101933"><a href="index_p.html#ixb101499"><font color=#000080><tt>processMouseEvent</tt></font></a></a>
+für das Handling von Mouse-Events zuständig:
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
+<tr>
+<td valign=top width=100%>
+<font color="#660066">
+<pre>
+protected void processEvent(AWTEvent e)
+
+protected void processComponentEvent(ComponentEvent e)
+
+protected void processFocusEvent(FocusEvent e)
+
+...
+</pre>
+</font>
+</td>
+<td valign=top>
+<a href="../jdkdocs/api/java/awt/Component.html" onClick="this.href=getApiDoc('java.awt.Component')"><font color="#660066" size=-1>java.awt.Component</font></a></td>
+</tr>
+</table>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=1></td>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Beide Methodenarten können in einer abgeleiteten Klasse überlagert
+werden, um die zugehörigen Ereignisempfänger zu implementieren.
+Wichtig ist dabei, dass in der abgeleiteten Klasse die gleichnamige
+Methode der Basisklasse aufgerufen wird, um das Standardverhalten
+sicherzustellen. Wichtig ist weiterhin, dass sowohl <a href="index_p.html#ixb101497"><font color=#000080><tt>processEvent</tt></font></a>
+als auch <a href="index_p.html#ixb101498"><font color=#000080><tt>processActionEvent</tt></font></a>
+usw. nur aufgerufen werden, wenn der entsprechende Ereignistyp für
+diese Ereignisquelle aktiviert wurde. Dies passiert in folgenden Fällen:
+<ul>
+<li>Wenn ein passender Ereignisempfänger über die zugehörige
+<font color="#000077"><tt>addEventListener</tt></font>-Methode registriert
+wurde.
+<li>Wenn der Ereignistyp explizit durch Aufruf der Methode <a name="ixa101934"><a href="index_e.html#ixb101500"><font color=#000080><tt>enableEvents</tt></font></a></a>
+aktiviert wurde.
+</ul>
+</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#CC0000">
+<tr>
+<td><font color="#FFFFFF"> Warnung </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Die Methode <a href="index_e.html#ixb101500"><font color=#000080><tt>enableEvents</tt></font></a>
+erwartet als Argument eine Maske, die durch eine bitweise Oder-Verknüpfung
+der passenden Maskenkonstanten aus der Klasse <a name="ixa101935"><a href="index_a.html#ixb101402"><font color=#000080><tt>AWTEvent</tt></font></a></a>
+zusammengesetzt werden kann:
+
+<p>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
+<tr>
+<td valign=top width=100%>
+<font color="#660066">
+<pre>
+protected final void enableEvents(long eventsToEnable)
+</pre>
+</font>
+</td>
+<td valign=top>
+<a href="../jdkdocs/api/java/awt/Component.html" onClick="this.href=getApiDoc('java.awt.Component')"><font color="#660066" size=-1>java.awt.Component</font></a></td>
+</tr>
+</table>
+
+<p>
+Die verfügbaren Masken sind analog zu den Ereignistypen benannt
+und heißen <a name="ixa101936"><a href="index_a.html#ixb101501"><font color=#000080><tt>ACTION_EVENT_MASK</tt></font></a></a>,
+<a name="ixa101937"><a href="index_a.html#ixb101502"><font color=#000080><tt>ADJUSTMENT_EVENT_MASK</tt></font></a></a>,
+<a name="ixa101938"><a href="index_c.html#ixb101503"><font color=#000080><tt>COMPONENT_EVENT_MASK</tt></font></a></a>
+usw.
+
+<p>
+Das folgende Beispiel überlagert die Methode <a name="ixa101939"><a href="index_p.html#ixb101504"><font color=#000080><tt>processKeyEvent</tt></font></a></a>
+in der Klasse <a href="index_f.html#ixb101144"><font color=#000080><tt>Frame</tt></font></a>
+(die sie aus <a href="index_c.html#ixb101302"><font color=#000080><tt>Component</tt></font></a>
+geerbt hat). Durch Aufruf von <a href="index_e.html#ixb101500"><font color=#000080><tt>enableEvents</tt></font></a>
+wird die Weiterleitung der Tastaturereignisse aktiviert, und das Programm
+zeigt dasselbe Verhalten wie die vorigen Programme.
+<a name="listingid028006"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing2806.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.awt.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.awt.event.*;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2806
+<font color="#555555">007 </font><font color="#0000AA">extends</font> Frame
+<font color="#555555">008 </font>{
+<font color="#555555">009 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">010 </font> {
+<font color="#555555">011 </font> Listing2806 wnd = <font color="#0000AA">new</font> Listing2806();
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font>
+<font color="#555555">014 </font> <font color="#0000AA">public</font> Listing2806()
+<font color="#555555">015 </font> {
+<font color="#555555">016 </font> <font color="#006699">super</font>(<font color="#0000FF">"Nachrichtentransfer"</font>);
+<font color="#555555">017 </font> setBackground(Color.lightGray);
+<font color="#555555">018 </font> setSize(300,200);
+<font color="#555555">019 </font> setLocation(200,100);
+<font color="#555555">020 </font> setVisible(<font color="#006699">true</font>);
+<font color="#555555">021 </font> enableEvents(AWTEvent.KEY_EVENT_MASK);
+<font color="#555555">022 </font> }
+<font color="#555555">023 </font>
+<font color="#555555">024 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> paint(Graphics g)
+<font color="#555555">025 </font> {
+<font color="#555555">026 </font> g.setFont(<font color="#0000AA">new</font> Font(<font color="#0000FF">"Serif"</font>,Font.PLAIN,18));
+<font color="#555555">027 </font> g.drawString(<font color="#0000FF">"Zum Beenden bitte ESC drücken..."</font>,10,50);
+<font color="#555555">028 </font> }
+<font color="#555555">029 </font>
+<font color="#555555">030 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> processKeyEvent(KeyEvent event)
+<font color="#555555">031 </font> {
+<font color="#555555">032 </font> <font color="#0000AA">if</font> (event.getID() == KeyEvent.KEY_PRESSED) {
+<font color="#555555">033 </font> <font color="#0000AA">if</font> (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
+<font color="#555555">034 </font> setVisible(<font color="#006699">false</font>);
+<font color="#555555">035 </font> dispose();
+<font color="#555555">036 </font> System.exit(0);
+<font color="#555555">037 </font> }
+<font color="#555555">038 </font> }
+<font color="#555555">039 </font> <font color="#006699">super</font>.processKeyEvent(event);
+<font color="#555555">040 </font> }
+<font color="#555555">041 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing2806.java"><font color="#000055" size=-1>Listing2806.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 28.6: Überlagern der Komponenten-Event-Handler</i></p>
+
+<p>
+Diese Art der Ereignisbehandlung ist nur sinnvoll, wenn Fensterklassen
+oder Dialogelemente überlagert werden und ihr Aussehen oder Verhalten
+signifikant verändert wird. Alternativ könnte natürlich
+auch in diesem Fall ein <a href="index_e.html#ixb101396"><font color=#000080><tt>EventListener</tt></font></a>
+implementiert und die entsprechenden Methoden im Konstruktor der abgeleiteten
+Klasse registriert werden.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Das hier vorgestellte Verfahren umgeht das Delegation Event Model
+vollständig und hat damit die gleichen inhärenten Nachteile
+wie das Event-Handling des alten JDK. Die Dokumentation zum JDK empfiehlt
+daher ausdrücklich, für alle »normalen« Anwendungsfälle
+das Delegation Event Model zu verwenden und die Anwendungen nach einem
+der in den ersten drei Beispielen genannten Entwurfsmuster zu implementieren.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel3id028002005"></a>
+<h3>28.2.5 Ausblick </h3>
+
+<p>
+Die hier vorgestellten Entwurfsmuster geben einen Überblick über
+die wichtigsten Designtechniken für das Event-Handling in Java-Programmen.
+Während die ersten beiden Beispiele für kleine bis mittelgroße
+Programme gut geeignet sind, kommen die Vorteile der in Variante 3
+vorgestellten Trennung zwischen GUI-Code und Anwendungslogik vor allem
+bei größeren Programmen zum Tragen. Die vierte Variante
+ist vornehmlich für Spezialfälle geeignet und sollte entsprechend
+umsichtig eingesetzt werden.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Wir werden in den nachfolgenden Kapiteln vorwiegend die ersten beiden
+Varianten einsetzen. Wenn es darum geht, Ereignishandler für
+die Beispielprogramme zu implementieren, werden wir also entweder
+die erforderlichen Listener-Interfaces in der Fensterklasse selbst
+implementieren oder sie in lokalen oder anonymen Klassen unterbringen.
+Da das Event-Handling des JDK 1.1 eine Vielzahl von Designvarianten
+erlaubt, werden wir uns nicht immer sklavisch an die vorgestellten
+Entwurfsmuster halten, sondern teilweise leicht davon abweichen oder
+Mischformen verwenden. Dies ist beabsichtigt und soll den möglichen
+Formenreichtum demonstrieren. Wo nötig, werden wir auf spezielle
+Implementierungsdetails gesondert eingehen.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+<a href="k100184.html#kapitellowlevelevents">Kapitel 29</a> widmet
+sich den wichtigsten Low-Level-Events und demonstriert den genauen
+Einsatz ihrer Listener- und Event-Methoden anhand vieler Beispiele.
+In späteren Kapiteln werden die meisten der High-Level-Events
+erläutert. Sie werden in der Regel dort eingeführt, wo ihr
+Einsatz durch das korrespondierende Dialogelement motiviert wird.
+So erläutert <a href="k100192.html#kapitelmenues">Kapitel 30</a>
+in Zusammenhang mit der Vorstellung von Menüs die Action-Ereignisse,
+und in <a href="k100206.html#kapitelawtdialogelemente">Kapitel 32</a>
+werden Ereignisse erläutert, die von den dort vorgestellten Dialogelementen
+ausgelöst werden.
+<hr>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
+Wesley, Version 5.0.1
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100180.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100181.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100183.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100184.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">© 1998, 2007 Guido Krüger & Thomas
+Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
+</table>
+<a name="endofbody"></a>
+</body>
+</html>
|
