summaryrefslogtreecommitdiffstats
path: root/Master/Reference Architectures and Patterns/hjp5/html/k100199.html
blob: 7adafcdf02de50ea141a93624ab9f5edfec2a5fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
<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,k100192.html;106,k100198.html;107,k100200.html;108,k100201.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">&nbsp;Titel&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html">&nbsp;Inhalt&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html">&nbsp;Suchen&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html">&nbsp;Index&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()">&nbsp;DOC&nbsp;</a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100192.html">&nbsp;&lt;&lt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100198.html">&nbsp;&nbsp;&lt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100200.html">&nbsp;&nbsp;&gt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100201.html">&nbsp;&gt;&gt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()">&nbsp;API&nbsp;</a>
<td align="right">Kapitel 30 - Men&uuml;s
</table>
<hr>


<!-- Section -->
<a name="sectlevel2id030007"></a>
<h2>30.7 Datenaustausch mit der <a name="ixa102067">Zwischenablage</a>
</h2>
<hr>
<ul>
<li><a href="k100199.html#sectlevel2id030007">30.7 Datenaustausch mit der Zwischenablage</a>
<ul>
<li><a href="k100199.html#sectlevel3id030007001">30.7.1 &Uuml;berblick</a>
<li><a href="k100199.html#sectlevel3id030007002">30.7.2 Kommunikation mit der Zwischenablage</a>
</ul>
</ul>
<hr>


<!-- Section -->
<a name="sectlevel3id030007001"></a>
<h3>30.7.1 &Uuml;berblick </h3>

<p>
Die Zwischenablage ist in grafischen Oberfl&auml;chen eines der wichtigsten
Hilfsmittel, um Daten zwischen Dialogelementen oder &uuml;ber Anwendungsgrenzen
hinweg auszutauschen. Seit dem JDK 1.1 gibt es ein allgemeines API
f&uuml;r den Datenaustausch, das Funktionen f&uuml;r den Datenaustausch
mit der Zwischenablage zur Verf&uuml;gung stellt. Wir wollen es hier
kurz beschreiben, weil es als typisches Element eines Kontextmen&uuml;s
gut in den Rahmen dieses Kapitels passt. 

<p>
Die zugeh&ouml;rigen Klassen und Interfaces befinden sich im Paket
<a name="ixa102068"><a href="index_j.html#ixb101578"><font color=#000080><tt>java.awt.datatransfer</tt></font></a></a>.
Die f&uuml;r die Kommunikation mit der Zwischenablage interessanten
Bestandteile dieses APIs sind: 
<ul>
<li>Das Interface <a name="ixa102069"><a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a></a>,
das die Schnittstelle von Objekten festlegt, die mit der Zwischenablage
ausgetauscht werden k&ouml;nnen.
<li>Die Definition der Datentypen, die ausgetauscht werden k&ouml;nnen.
Diese werden in Java als <a name="ixa102070"><i>DataFlavors</i></a>
bezeichnet und basieren auf der <a name="ixa102071"><i>MIME-Spezifikation</i></a>
(<i>Multi-purpose Internet Mail Extensions</i>), die in <a name="ixa102072">RFC 1521</a>
und <a name="ixa102073">1522</a> beschrieben wird (allgemeine Hinweise
zu den RFCs finden sich in <a href="k100293.html#requestforcomments">Abschnitt 46.1.5</a>).
<li>Die Klasse <a name="ixa102074"><a href="index_c.html#ixb101584"><font color=#000080><tt>Clipboard</tt></font></a></a>,
mit der die Zwischenablage implementiert wird. Neben der systemweiten
Zwischenablage k&ouml;nnen auch benutzerdefinierte Zwischenablagen
verwendet werden.
</ul>


<!-- Section -->
<a name="sectlevel3id030007002"></a>
<h3>30.7.2 Kommunikation mit der Zwischenablage </h3>

<p>
Wir wollen uns nun ansehen, welche Schritte erforderlich sind, um
einen <a href="index_s.html#ixb100117"><font color=#000080><tt>String</tt></font></a>
in die Zwischenablage zu kopieren. Zun&auml;chst muss ein Objekt erzeugt
werden, das das Interface <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>
implementiert. <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>
spezifiziert die Schnittstelle f&uuml;r den Transportmechanismus von
Daten, die &uuml;ber die Zwischenablage ausgetauscht werden k&ouml;nnen.
Es verwaltet eine Liste der in Frage kommenden Datentypen, die es
mit <a name="ixa102075"><a href="index_g.html#ixb101585"><font color=#000080><tt>getTransferDataFlavors</tt></font></a></a>
auf Anfrage zur Verf&uuml;gung stellt. Mit <a name="ixa102076"><a href="index_i.html#ixb101586"><font color=#000080><tt>isDataFlavorSupported</tt></font></a></a>
kann festgestellt werden, ob ein bestimmter Datentyp unterst&uuml;tzt
wird, und <a name="ixa102077"><a href="index_g.html#ixb101587"><font color=#000080><tt>getTransferData</tt></font></a></a>
liefert die zu &uuml;bertragenden Daten: 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public DataFlavor[] getTransferDataFlavors()

public boolean isDataFlavorSupported(DataFlavor flavor)

public Object getTransferData(DataFlavor flavor)
  throws UnsupportedFlavorException, IOException
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/awt/datatransfer/Transferable.html" onClick="this.href=getApiDoc('java.awt.datatransfer.Transferable')"><font color="#660066" size=-1>java.awt.datatransfer.Transferable</font></a></td>
</tr>
</table>
<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>
Die Initialisierung eines <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>-Objekts
ist nicht Bestandteil der Schnittstelle, sondern muss von den implementierenden
Klassen in Eigenregie - beispielsweise bei der Instanzierung - vorgenommen
werden.</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">&nbsp;Hinweis&nbsp;</font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
</tr>
</table>

<p>
Im AWT gibt es eine vordefinierte Klasse <a name="ixa102078"><a href="index_s.html#ixb101588"><font color=#000080><tt>StringSelection</tt></font></a></a>,
die das Interface <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>
implementiert. Sie ist in der Lage, Strings auszutauschen, und unterst&uuml;tzt
die aus <a name="ixa102079"><a href="index_d.html#ixb101589"><font color=#000080><tt>DataFlavor</tt></font></a></a>
abgeleiteten Datentypen <a name="ixa102080"><a href="index_p.html#ixb101590"><font color=#000080><tt>plainTextFlavor</tt></font></a></a>
und <a name="ixa102081"><a href="index_s.html#ixb101591"><font color=#000080><tt>stringFlavor</tt></font></a></a>.
Beide liefern die Daten als Unicode-kodierte Zeichenkette. W&auml;hrend
<a href="index_p.html#ixb101590"><font color=#000080><tt>plainTextFlavor</tt></font></a>
sein Ergebnis als <a href="index_i.html#ixb100642"><font color=#000080><tt>InputStream</tt></font></a>
zur Verf&uuml;gung stellt und den MIME-Typ <font color="#000077"><tt>text/plain</tt></font>
repr&auml;sentiert, liefert <a href="index_s.html#ixb101591"><font color=#000080><tt>stringFlavor</tt></font></a>
einen String und repr&auml;sentiert den MIME-Typ <font color="#000077"><tt>application/x-java-serialized-object</tt></font>.

<p>
Ein <a href="index_s.html#ixb101588"><font color=#000080><tt>StringSelection</tt></font></a>-Objekt
wird initialisiert, indem die zu &uuml;bertragende Zeichenkette an
den Konstruktor &uuml;bergeben wird. Anschlie&szlig;end kann es an
die Zwischenablage &uuml;bergeben werden, die die Daten durch Aufruf
von <a href="index_g.html#ixb101587"><font color=#000080><tt>getTransferData</tt></font></a>
&uuml;bernimmt. Jeder Aufruf von <a href="index_g.html#ixb101587"><font color=#000080><tt>getTransferData</tt></font></a>
muss in eine <a href="index_t.html#ixb100569"><font color=#000080><tt>try</tt></font></a>-<a href="index_c.html#ixb100570"><font color=#000080><tt>catch</tt></font></a>-Anweisung
eingebunden werden und folgende Fehler abfangen: 
<ul>
<li>Das <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>-Objekt
ist nicht in der Lage, die Daten in dem gew&uuml;nschten Format zu
liefern.
<li>Da der R&uuml;ckgabewert vom Typ <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
ist, muss er in der Regel in den tats&auml;chlich erforderlichen Typ
konvertiert werden. Hierbei kann eine Ausnahme des Typs <a name="ixa102082"><a href="index_c.html#ixb100729"><font color=#000080><tt>ClassCastException</tt></font></a></a>
auftreten.
</ul>

<p>
Bevor die Zwischenablage die Daten aus dem <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>-Objekt
entnehmen kann, muss dieses nat&uuml;rlich erst einmal an die Zwischenablage
&uuml;bergeben werden. Eine Zwischenablage ist immer eine Instanz
der Klasse <a href="index_c.html#ixb101584"><font color=#000080><tt>Clipboard</tt></font></a>
oder einer ihrer Unterklassen. Zwar ist es m&ouml;glich, anwendungsspezifische
Zwischenablagen anzulegen, wir wollen uns aber nur mit der systemweit
g&uuml;ltigen Zwischenablage des Betriebssystems besch&auml;ftigen.

<p>
Im <a href="index_t.html#ixb100506"><font color=#000080><tt>Toolkit</tt></font></a>
gibt es eine Methode <a name="ixa102083"><a href="index_g.html#ixb101592"><font color=#000080><tt>getSystemClipboard</tt></font></a></a>,
mit der ein Objekt f&uuml;r die systemweite Zwischenablage beschafft
werden kann: 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public Clipboard getSystemClipboard()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/awt/Toolkit.html" onClick="this.href=getApiDoc('java.awt.Toolkit')"><font color="#660066" size=-1>java.awt.Toolkit</font></a></td>
</tr>
</table>

<p>
Sie stellt im wesentlichen einen Konstruktor und drei Methoden zur
Verf&uuml;gung: 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public String getName()

public Transferable getContents(Object requestor)

public void setContents(
   Transferable contents, ClipboardOwner owner
)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/awt/datatransfer/Clipboard.html" onClick="this.href=getApiDoc('java.awt.datatransfer.Clipboard')"><font color="#660066" size=-1>java.awt.datatransfer.Clipboard</font></a></td>
</tr>
</table>

<p>
Mit <a name="ixa102084"><a href="index_g.html#ixb100667"><font color=#000080><tt>getName</tt></font></a></a>
kann der Name der Zwischenablage ermittelt werden, <a name="ixa102085"><a href="index_g.html#ixb101593"><font color=#000080><tt>getContents</tt></font></a></a>
liefert den Inhalt der Zwischenablage, und mit <a name="ixa102086"><a href="index_s.html#ixb101594"><font color=#000080><tt>setContents</tt></font></a></a>
kann der Zwischenablage ein neues Objekt zugewiesen werden. Ein Aufruf
von <a href="index_g.html#ixb101593"><font color=#000080><tt>getContents</tt></font></a>
liefert null, wenn die Zwischenablage leer ist. Der R&uuml;ckgabewert
ist ein <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>-Objekt,
dessen Daten mit <a href="index_g.html#ixb101587"><font color=#000080><tt>getTransferData</tt></font></a>
abgefragt werden k&ouml;nnen. Beim Aufruf von <a href="index_g.html#ixb101593"><font color=#000080><tt>getContents</tt></font></a>
muss zus&auml;tzlich ein Objekt <font color="#000077"><tt>requestor</tt></font>
&uuml;bergeben werden, das derzeit keine Funktion hat. 

<p>
Ein Objekt, das den Inhalt der Zwischenablage &auml;ndern will, tut
dies &uuml;ber den Aufruf der Methode <a href="index_s.html#ixb101594"><font color=#000080><tt>setContents</tt></font></a>.
Als erstes Argument ist ein <a href="index_t.html#ixb101579"><font color=#000080><tt>Transferable</tt></font></a>-Objekt
zu &uuml;bergeben, das die Daten enth&auml;lt. Als zweites muss ein
Objekt &uuml;bergeben werden, das das Interface <a name="ixa102087"><a href="index_c.html#ixb101595"><font color=#000080><tt>ClipboardOwner</tt></font></a></a>
implementiert. Da die Zwischenablage von verschiedenen Objekten verwendet
wird, ist es unter Umst&auml;nden wichtig zu wissen, wann die &uuml;bergebenen
Daten verworfen und durch ein neues Objekt ersetzt werden. Dazu definiert
<a href="index_c.html#ixb101595"><font color=#000080><tt>ClipboardOwner</tt></font></a>
die Methode <a name="ixa102088"><a href="index_l.html#ixb101596"><font color=#000080><tt>lostOwnership</tt></font></a></a>,
die aufgerufen wird, wenn der Inhalt der Zwischenablage ver&auml;ndert
wird: 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public void lostOwnership(
   Clipboard clipboard, Transferable contents
)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/awt/datatransfer/ClipboardOwner.html" onClick="this.href=getApiDoc('java.awt.datatransfer.ClipboardOwner')"><font color="#660066" size=-1>java.awt.datatransfer.ClipboardOwner</font></a></td>
</tr>
</table>

<p>
Nach diesen Vor&uuml;berlegungen wollen wir uns ein Beispiel ansehen.
Dazu soll die Methode <a href="index_a.html#ixb101474"><font color=#000080><tt>actionPerformed</tt></font></a>
des vorigen Beispiels erweitert werden, um die beiden Men&uuml;eintr&auml;ge
&#187;Kopieren&#171; und &#187;Einfuegen&#171; mit Funktionalit&auml;t
zum Datenaustausch auszustatten. Zus&auml;tzlich implementiert das
Beispielprogramm das Interface <a href="index_c.html#ixb101595"><font color=#000080><tt>ClipboardOwner</tt></font></a>
und definiert dazu die Methode <a href="index_l.html#ixb101596"><font color=#000080><tt>lostOwnership</tt></font></a>:
<a name="listingid030007"></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">/* clpbrd.inc */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#006699">void</font> actionPerformed(ActionEvent event)
<font color="#555555">004 </font>{
<font color="#555555">005 </font>  Clipboard clip = getToolkit().getSystemClipboard();
<font color="#555555">006 </font>  String cmd = event.getActionCommand();
<font color="#555555">007 </font>  <font color="#0000AA">if</font> (cmd.equals(<font color="#0000FF">"Kopieren"</font>)) {
<font color="#555555">008 </font>    String s = <font color="#0000FF">"Es ist "</font> + System.currentTimeMillis() + <font color="#0000FF">"Uhr"</font>;
<font color="#555555">009 </font>    StringSelection cont = <font color="#0000AA">new</font> StringSelection(s);
<font color="#555555">010 </font>    clip.setContents(cont, <font color="#006699">this</font>);
<font color="#555555">011 </font>  } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (cmd.equals(<font color="#0000FF">"Einfuegen"</font>)) {
<font color="#555555">012 </font>    Transferable cont = clip.getContents(<font color="#006699">this</font>);
<font color="#555555">013 </font>    <font color="#0000AA">if</font> (cont == <font color="#006699">null</font>) {
<font color="#555555">014 </font>      System.out.println(<font color="#0000FF">"Zwischenablage ist leer"</font>);
<font color="#555555">015 </font>    } <font color="#0000AA">else</font> {
<font color="#555555">016 </font>      <font color="#0000AA">try</font> {
<font color="#555555">017 </font>        String s = (String) cont.getTransferData(
<font color="#555555">018 </font>          DataFlavor.stringFlavor
<font color="#555555">019 </font>        );
<font color="#555555">020 </font>        System.out.println(s);
<font color="#555555">021 </font>      } <font color="#0000AA">catch</font> (Exception e) {
<font color="#555555">022 </font>        System.out.println(
<font color="#555555">023 </font>          <font color="#0000FF">"Zwischenablage enth&auml;lt keinen Text"</font>
<font color="#555555">024 </font>        );
<font color="#555555">025 </font>      }
<font color="#555555">026 </font>    }
<font color="#555555">027 </font>  }
<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> lostOwnership(Clipboard clip, Transferable cont)
<font color="#555555">031 </font>{
<font color="#555555">032 </font>  System.out.println(<font color="#0000FF">"Inhalt der Zwischenablage ersetzt"</font>);
<font color="#555555">033 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/clpbrd.inc"><font color="#000055" size=-1>clpbrd.inc</font></a></td>
</tr>
</table>
<i>
Listing 30.7: Kommunikation mit der Zwischenablage</i></p>
<hr>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html">&nbsp;Titel&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html">&nbsp;Inhalt&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html">&nbsp;Suchen&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html">&nbsp;Index&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()">&nbsp;DOC&nbsp;</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="k100192.html">&nbsp;&lt;&lt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100198.html">&nbsp;&nbsp;&lt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100200.html">&nbsp;&nbsp;&gt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100201.html">&nbsp;&gt;&gt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()">&nbsp;API&nbsp;</a>
<td align="right">&copy; 1998, 2007 Guido Kr&uuml;ger &amp; Thomas
Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
</table>
<a name="endofbody"></a>
</body>
</html>