Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage
 <<    <     >    >>   API  Kapitel 30 - Menüs

30.7 Datenaustausch mit der Zwischenablage



30.7.1 Überblick

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

Die zugehörigen Klassen und Interfaces befinden sich im Paket java.awt.datatransfer. Die für die Kommunikation mit der Zwischenablage interessanten Bestandteile dieses API sind:

30.7.2 Kommunikation mit der Zwischenablage

Wir wollen uns nun ansehen, welche Schritte erforderlich sind, um einen String in die Zwischenablage zu kopieren. Zunächst muss ein Objekt erzeugt werden, das das Interface Transferable implementiert. Transferable spezifiziert die Schnittstelle für den Transportmechanismus von Daten, die über die Zwischenablage ausgetauscht werden können. Es verwaltet eine Liste der in Frage kommenden Datentypen, die es mit getTransferDataFlavors auf Anfrage zur Verfügung stellt. Mit isDataFlavorSupported kann festgestellt werden, ob ein bestimmter Datentyp unterstützt wird, und getTransferData liefert die zu übertragenden Daten:

public DataFlavor[] getTransferDataFlavors()

public boolean isDataFlavorSupported(DataFlavor flavor)

public Object getTransferData(DataFlavor flavor)
  throws UnsupportedFlavorException, IOException
java.awt.datatransfer.Transferable

Die Initialisierung eines Transferable-Objekts ist nicht Bestandteil der Schnittstelle, sondern muss von den implementierenden Klassen in Eigenregie - beispielsweise bei der Instanzierung - vorgenommen werden.

Im AWT gibt es eine vordefinierte Klasse StringSelection, die das Interface Transferable implementiert. Sie ist in der Lage, Strings auszutauschen, und unterstützt die aus DataFlavor abgeleiteten Datentypen plainTextFlavor und stringFlavor. Beide liefern die Daten als Unicode-kodierte Zeichenkette. Während plainTextFlavor sein Ergebnis als InputStream zur Verfügung stellt und den MIME-Typ text/plain repräsentiert, liefert stringFlavor einen String und repräsentiert den MIME-Typ application/x-java-serialized-object.

Ein StringSelection-Objekt wird initialisiert, indem die zu übertragende Zeichenkette an den Konstruktor übergeben wird. Anschließend kann es an die Zwischenablage übergeben werden, die die Daten durch Aufruf von getTransferData übernimmt. Jeder Aufruf von getTransferData muss in eine try-catch-Anweisung eingebunden werden und folgende Fehler abfangen:

Bevor die Zwischenablage die Daten aus dem Transferable-Objekt entnehmen kann, muss dieses natürlich erst einmal an die Zwischenablage übergeben werden. Eine Zwischenablage ist immer eine Instanz der Klasse Clipboard oder einer ihrer Unterklassen. Zwar ist es möglich, anwendungsspezifische Zwischenablagen anzulegen, wir wollen uns aber nur mit der systemweit gültigen Zwischenablage des Betriebssystems beschäftigen.

Im Toolkit gibt es eine Methode getSystemClipboard, mit der ein Objekt für die systemweite Zwischenablage beschafft werden kann:

public Clipboard getSystemClipboard()
java.awt.Toolkit

Sie stellt im Wesentlichen einen Konstruktor und drei Methoden zur Verfügung:

public String getName()

public Transferable getContents(Object requestor)

public void setContents(
   Transferable contents, ClipboardOwner owner
)
java.awt.datatransfer.Clipboard

Mit getName kann der Name der Zwischenablage ermittelt werden, getContents liefert den Inhalt der Zwischenablage und mit setContents kann der Zwischenablage ein neues Objekt zugewiesen werden. Ein Aufruf von getContents liefert null, wenn die Zwischenablage leer ist. Der Rückgabewert ist ein Transferable-Objekt, dessen Daten mit getTransferData abgefragt werden können. Beim Aufruf von getContents muss zusätzlich ein Objekt requestor übergeben werden, das derzeit keine Funktion hat.

Ein Objekt, das den Inhalt der Zwischenablage ändern will, tut dies über den Aufruf der Methode setContents. Als erstes Argument ist ein Transferable-Objekt zu übergeben, das die Daten enthält. Als zweites Argument muss ein Objekt übergeben werden, das das Interface ClipboardOwner implementiert. Da die Zwischenablage von verschiedenen Objekten verwendet wird, ist es unter Umständen wichtig zu wissen, wann die übergebenen Daten verworfen und durch ein neues Objekt ersetzt werden. Dazu definiert ClipboardOwner die Methode lostOwnership, die aufgerufen wird, wenn der Inhalt der Zwischenablage verändert wird:

public void lostOwnership(
   Clipboard clipboard, Transferable contents
)
java.awt.datatransfer.ClipboardOwner

Nach diesen Vorüberlegungen wollen wir uns ein Beispiel ansehen. Darin soll die Methode actionPerformed des vorigen Beispiels erweitert werden, um die beiden Menüeinträge »Kopieren« und »Einfuegen« mit Funktionalität zum Datenaustausch auszustatten. Zusätzlich implementiert das Beispielprogramm das Interface ClipboardOwner und definiert dazu die Methode lostOwnership:

001 /* clpbrd.inc */
002 
003 public void actionPerformed(ActionEvent event)
004 {
005   Clipboard clip = getToolkit().getSystemClipboard();
006   String cmd = event.getActionCommand();
007   if (cmd.equals("Kopieren")) {
008     String s = "Es ist " + System.currentTimeMillis() + "Uhr";
009     StringSelection cont = new StringSelection(s);
010     clip.setContents(cont, this);
011   } else if (cmd.equals("Einfuegen")) {
012     Transferable cont = clip.getContents(this);
013     if (cont == null) {
014       System.out.println("Zwischenablage ist leer");
015     } else {
016       try {
017         String s = (String) cont.getTransferData(
018           DataFlavor.stringFlavor
019         );
020         System.out.println(s);
021       } catch (Exception e) {
022         System.out.println(
023           "Zwischenablage enthält keinen Text"
024         );
025       }
026     }
027   }
028 }
029 
030 public void lostOwnership(Clipboard clip, Transferable cont)
031 {
032   System.out.println("Inhalt der Zwischenablage ersetzt");
033 }
clpbrd.inc
Listing 30.7: Kommunikation mit der Zwischenablage


 Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0
 <<    <     >    >>   API  © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de