Java-Tipp 61: Ausschneiden, Kopieren und Einfügen in Java

Dieser Artikel vermittelt Ihnen ein gutes Verständnis für das Senden und Abrufen von Informationen aus der Zwischenablage in Java. Sie lernen auch, wie Sie mit den verschiedenen verfügbaren Datenvarianten umgehen. Schließlich werden wir uns mit den verschiedenen Persönlichkeiten von Zwischenablagen befassen und wie sie mehr als eine Datenvariante unterstützen.

Java bietet zwei Arten von Zwischenablagen: lokal und system. Lokale Zwischenablagen sind nur in der virtuellen Maschine verfügbar, in der Ihr Applet oder Ihre Anwendung ausgeführt wird. Im Gegensatz zu einigen Betriebssystemen, die Sie auf nur eine Zwischenablage beschränken, können Sie in Java jedoch so viele lokale Zwischenablagen verwenden, wie Sie möchten. Der Zugriff auf eine bestimmte lokale Zwischenablage ist so einfach wie der Name.

System-Zwischenablagen sind direkt mit dem Peer-Betriebssystem verknüpft, sodass Ihre Anwendung Informationen zwischen allen Anwendungen übertragen kann, die unter diesem Betriebssystem ausgeführt werden. Ein Nachteil der Verwendung der Systemzwischenablage besteht darin, dass Sie nur Textdaten übertragen können. Andere Objekttypen werden von der Systemzwischenablage nicht unterstützt. Mit etwas Glück wird dieses Problem in der nächsten Version des JDK behoben.

Bevor wir weiter gehen, werfen wir einen Blick auf alle Klassen, die an der Bearbeitung der Zwischenablage beteiligt sind. Diese in der folgenden Tabelle aufgeführten Klassen sind alle Teil des Pakets java.awt.datatransfer .

Liste aller Klassen im Paket java.awt.datatransfer
Name Art Beschreibung
Clipboard Klasse Beschäftigt sich mit allem, was übertragbar ist
ClipboardOwner Schnittstelle Jede Klasse, die sich mit der Zwischenablage befasst, muss diese Schnittstelle implementieren. Diese Schnittstelle wird verwendet, um zu benachrichtigen, wenn die ursprünglich in der Zwischenablage abgelegten Daten überschrieben wurden
Dataflavor Klasse Repräsentiert alle Datentypen, die übertragbar sind
StringSelection Klasse Eine Art von Übertragbarkeit, die mit Java geliefert wird
Transferable Schnittstelle Wrapper für Objekte, die an die Zwischenablage übergeben werden
UnsupportedFlavor Exception Klasse Ausnahme von übertragbar für eine nicht unterstützte Datenvariante ausgelöst

Mehr zu den Zwischenablageklassen

Lassen Sie uns java.awt.datatransfernäher auf unsere Erkundung des Pakets eingehen, indem wir uns jede Klasse genauer ansehen.

Die Zwischenablage-Klasse

Die ClipboardKlasse ist Ihr Link zum Zugriff auf die Zwischenablage. Es enthält drei Methoden, die in der folgenden Tabelle definiert sind:

Zwischenablage Klasse
Methode Beschreibung
String getName () Holen Sie sich den Namen der Zwischenablage
void setContents (Transferable, ClipboardOwner) Legen Sie den Inhalt der Zwischenablage zusammen mit dem Eigentümerobjekt fest
Transferable getContent (Object) Holen Sie sich den Inhalt der Zwischenablage in Form eines übertragbaren Objekts. Das als Parameter übergebene Objekt ist der Eigentümer

Mit den drei oben genannten ClipboardKlassenmethoden können Sie die Zwischenablage benennen, Informationen an sie senden oder Informationen von ihr abrufen. Der Zugriff auf die Systemzwischenablage oder das Erstellen einer lokalen Zwischenablage ist anders und erfordert etwas mehr Diskussion. Um auf die Systemzwischenablage zuzugreifen, weisen Sie der ClipboardKlasse eine Referenz aus der Systemzwischenablage zu , z.

Clipboard clipboard = getToolkit ().getSystemClipboard ();

Zum Erstellen einer lokalen Zwischenablage müssen Sie jedoch nur ein ClipboardObjekt mit dem Namen erstellen , den Sie ihm zuweisen möchten, z. B.:

Clipboard clipboard = new Clipboard ("My first clipboard");

Der Zugriff auf die Systemzwischenablage oder das Erstellen einer lokalen Zwischenablage ist anders, aber unkompliziert.

Die ClipboardOwner-Oberfläche

Da Java eine plattformübergreifende Sprache ist und sich Betriebssysteme gegenüber Zwischenablagen anders verhalten, mussten die Autoren der Java-Sprache einen Mechanismus entwickeln, um mit subtilen Unterschieden umzugehen. Dies ist der Grund für das Vorhandensein der ClipboardOwnerSchnittstelle. Seine einzige Funktion besteht darin, den Eigentümer der Zwischenablage zu informieren, wenn seine Daten von einer anderen Person überschrieben werden. Es kann einer Anwendung auch signalisieren, wann eine mit den Daten verknüpfte Ressource freigegeben werden soll.

In einer realen Anwendung kann die lostOwnershipMethode verwendet werden, um ein Flag zu setzen, das Ihre Anwendung über die Verfügbarkeit der Daten in der Zwischenablage informiert. Microsoft Word ist zwar nicht in Java geschrieben, aber ein gutes Beispiel für diesen Mechanismus bei der Arbeit in einer Anwendung. Immer wenn Sie in Word etwas in die Zwischenablage einfügen und dann beenden, wird ein Dialogfeld angezeigt, in dem Sie darüber informiert werden, dass sich Daten in der Zwischenablage befinden. Sie werden dann gefragt, ob Sie die Daten in der Zwischenablage belassen möchten.

Die Implementierung der ClipboardOwnerSchnittstelle ist relativ einfach, da nur eine Methode implementiert werden kann. Diese Methode führt dazu, dass Ihr Programm den Besitz der Zwischenablage aufgibt.

Die DataFlavor-Klasse

Die DataFlavorKlasse wird verwendet, um den Typ eines Objekts darzustellen . Sie sind nicht auf eine Datenvariante (oder einen Datentyp) pro Objekt beschränkt. Und wie wir können Ihre Objekte mehrere Persönlichkeiten haben! Beispielsweise kann eine Bildklasse als Java-Klasse oder als Array von Bits (GIF, JPEG usw.) dargestellt werden. In Wirklichkeit ist eine DataFlavorKlasse ein Wrapper für einen MIME-Typ. Der MIME-Standard ist umfangreich, daher sind den Daten, die in die Zwischenablage übertragen werden können, praktisch keine Grenzen gesetzt. (Eine Diskussion über den MIME-Standard ist nicht Gegenstand dieses Artikels. Weitere Informationen finden Sie jedoch im Abschnitt Ressourcen.)

Als Beispiel für eine Datenvariante werden Sie feststellen, dass die StringSelectionKlasse zwei auf MIME-Typen basierende Varianten aufweist. Bei der Implementierung ist "application / x-java-serialized-object" und die zweite ist "text / plain; charset = unicode". Tatsächlich sagt uns diese Implementierung, dass wir Text als StringKlasse ( application/x-java-serialized-object) oder als Klartext ( text/plain; charset=unicode) aus der Zwischenablage abrufen können .

Es gibt zwei Möglichkeiten, eine zu erstellen DataFlavor. Du kannst schreiben:

public DataFlavor (representationClass, String humanRepresentationName)

Dieser Konstruktor erstellt eine neue Datenvariante, die eine Java-Klasse darstellt. Die zurückgegebenen DataFlavorhaben representationClass = representationClassund a mimeType = application/x-java-serialized-object. Als Beispiel würde das Folgende ein DataFlavorfür das erstellen java.awt.Button:

DataFlavor (Class.forName ("java.awt.Button"), "AWT Button");

Nun dieser zweite Konstruktor

public DataFlavor (String mimeType, String humanRepresentationName)

wird eine DataFlavormit a konstruieren MimeType. Die DataFlavorRücksendung basiert auf dem MimeType. Wenn dies der Fall MimeTypeist application/x-java-serialized-object, ist das Ergebnis dasselbe, als hätten Sie den vorherigen Konstruktor aufgerufen. Trotzdem wird die Rückgabe DataFlavorerfolgen representationClass= InputStream and mimeType =mimeType. Der folgende Aufruf würde beispielsweise eine Nur-Text-Variante erzeugen:

public DataFlavor ("text/plain; charset=unicode", "Unicode");

Die folgende Tabelle zeigt die Methoden der DataFlavorKlasse.

DataFlavor-Klasse
Methoden Beschreibung
boolean equals (DataFlavor) Testen Sie, ob der bereitgestellte DataFlavor dem von dieser Klasse dargestellten DataFlavor entspricht
String getHumanPresentableName () Gibt den vom Menschen darstellbaren Namen für das Format zurück, das dieser DataFlavor darstellt
void setHumanPresentableName (String) Legen Sie den Namen der menschlichen Darstellung für diesen DataFlavor fest
String getMimeType () Ruft die Zeichenfolge vom Typ MIME ab, die von diesem DataFlavor dargestellt wird
Class getRepresentationClass () Geben Sie die Klasse zurück, die diese Klasse darstellt

Die übertragbare Schnittstelle

Die TransferableSchnittstelle muss von allen Klassen implementiert werden, die Sie an die Zwischenablage senden möchten. Daher versteht die ClipboardKlasse nur Klassen, die von der TransferableSchnittstelle umbrochen wurden . Die TransferableSchnittstelle besteht aus drei Methoden:

Übertragbare Schnittstelle
Methoden Beschreibung
DataFlavor getTransferDataFlavor () Gibt ein Array von DataFlavor zurück, das das Objekt darstellt
boolean isDataFlavorSupported (DataFlavor) Testen Sie, ob das mitgelieferte DataFlavor unterstützt wird
Object getTransferData (DataFlavor) Geben Sie das Objekt zurück, das vom bereitgestellten DataFlavor dargestellt wird

Damit ist unsere Tour durch alle Klassen abgeschlossen, die mit der Handhabung der Zwischenablage befasst sind. Wir haben gesehen, dass wir zum Zugriff auf die Zwischenablage entweder ein ClipboardObjekt erstellen oder einen Verweis auf die Systemzwischenablage erhalten müssen. Da die Zwischenablage nur Objekte vom Typ akzeptiert Transferable, muss das Objekt, das Sie an die Zwischenablage senden möchten, diese Schnittstelle implementieren. Schließlich haben alle Objekte in der Zwischenablage Geschmacksrichtungen, die von der DataFlavorKlasse dargestellt werden, die in Wirklichkeit ein Wrapper für MIME-Typen ist.

In den nächsten Abschnitten werden wir das Gelernte in die Praxis umsetzen.

Das Rezept für die Verwendung in der Zwischenablage

Wie diese verschiedenen Klassen auf die Zwischenablage zugreifen, kann verwirrend sein. Glücklicherweise gibt es ein einfaches Rezept, das die folgenden Schritte umfasst:

Schritt 1. Erstellen Sie eine Klasse namens xxxxSelection . Hier sollte xxx den Typ benennen, der durch diese Geschmacksrichtung dargestellt wird. Zum Beispiel ImageSelectionwäre ein guter Name für einen Bildgeschmack. Diese Namenskonvention ist natürlich nur ein Vorschlag. Ich folge der etablierten Verwendungskonvention mit der StringSelectionim JDK bereitgestellten, aber Sie können diese Klasse beliebig benennen. Es ist wichtig zu beachten, dass dieses Objekt die Schnittstellen Transferableund ClipboardOwnerimplementieren muss. Wenn Sie Text übertragen möchten, StringSelectionsollte stattdessen die Klasse verwendet werden.

Schritt 2. Definieren Sie eine Klasse für den Zugriff auf die Zwischenablage . Verwenden Sie den folgenden Aufruf, um auf eine lokale Zwischenablage zuzugreifen : Clipboard clipboard = new Clipboard ("name"). Verwenden Sie stattdessen diesen Aufruf, um auf die Zwischenablage des Peer-Betriebssystems zuzugreifen : Clipboard clipboard = getToolkit ().getSystemClipboard ().

Schritt 3. Legen Sie den Inhalt der Zwischenablage fest . Verwenden Sie dazu die setContentMethode in der ClipboardKlasse, wobei der erste Parameter ein Objekt ist, das a implementiert Transferable( xxxxSelectionin Schritt 1 erstellte Klasse), und der zweite Parameter eine Referenz auf die Klasse ist, die diese Methode aufruft.

Schritt 4. Holen Sie sich den Inhalt der Zwischenablage . Verwenden Sie die getContentMethode in der ClipboardKlasse. Diese Methode gibt eine Typklasse zurück Transferable.

Schritt 5. Implementieren Sie eine 'Schnittoperation' . Dazu müssen Sie die Daten manuell löschen, sobald sie in die Zwischenablage kopiert wurden. Java bietet keine Implementierung einer Schnittoperation.

Nach dieser kurzen Tour durch die Klassen mit Manipulation der Zwischenablage folgen wir dem vorgeschlagenen Rezept, um ein einfaches Applet zu schreiben, das Text in die Zwischenablage des Systems überträgt.

Listing 1:

Lassen Sie uns dieses Applet untersuchen:

Listing 1:

Im Folgenden werden bestimmte Codezeilen in Listing 1 erläutert.

Zeile 9: Definieren Sie die Klasse applet1, um die AppletKlasse zu erweitern und die ClipboardOwnerSchnittstelle zu implementieren .

Zeile 17: Definieren Sie ein Zwischenablageobjekt.

Zeile 26: Legen Sie das Zwischenablageobjekt auf die Zwischenablage des Peer-Betriebssystems fest.

Zeilen 45 bis 47: Implementieren Sie die einzige Methode in dieser Schnittstelle. In diesem Artikel verwenden wir die lostOwnershipMethode nicht, sondern drucken einfach eine Nachricht auf der Konsole. Sie können mit dieser Methode experimentieren, indem Sie mit diesem Applet Text in die Zwischenablage kopieren und dann etwas anderes aus einer anderen Anwendung kopieren. Die Meldung "Verlust des Eigentums" sollte in der Java-Konsole angezeigt werden, da die Daten, die in der Zwischenablage (mithilfe des Java-Applets) abgelegt wurden, von der anderen Anwendung überschrieben wurden.

Zeile 52: Definieren Sie eine Klasse des Typs StringSelection, die eine Textdaten-Variante implementiert. Wir erhalten dann den Inhalt des Quelltextfeldes.

Zeile 53: Stellen Sie den Inhalt der Zwischenablage auf die fieldContentKlasse ein, die wir in der vorherigen Zeile definiert haben. Beachten Sie, dass wir den Eigentümer dieser Klasse, in diesem Fall dieses Applet, angeben müssen.

Zeile 61: Definieren Sie ein Objekt vom Typ Transferable, um den Inhalt der Zwischenablage zu erhalten.

Zeile 63: Überprüfen Sie zwei Dinge. Ist die Zwischenablage leer? Zweitens, ist der Inhalt der Zwischenablage der richtige Geschmack? In diesem Fall suchen wir nach einem stringFlavor.

Zeile 67: Ruft den Inhalt der Zwischenablage in einer Zeichenfolgenvariablen ab. Dazu rufen wir die getTransferDataMethode mit dem gewünschten Geschmack auf. In diesem Fall benötigen wir einen DataFlavor.stringFlavorTyp.

Zeile 69: Stellen Sie den Inhalt des Zieltextfelds auf den Inhalt der Zwischenablage ein.

Sie können mit diesem Applet experimentieren, indem Sie Text zwischen diesem Applet und einem anderen Java-Applet oder zwischen einem Java-Applet und einem nativen Programm wie Notepad für Benutzer von Microsoft Windows übertragen.

Listing 2:

Im zweiten Beispiel schreiben wir ein Applet, das ein Bild in die Zwischenablage kopiert. Das Bild wird seinen eigenen Geschmack implementieren.

Listing 2:

Im Folgenden werden bestimmte Codezeilen in Listing 2 erläutert.

Zeile 27: Erstellen Sie ein Zwischenablageobjekt, das auf eine lokale Zwischenablage verweist.

Zeile 41: Stellen Sie den sourImageRegler auf Image.gif.

Zeilen 44 bis 50: Implementieren Sie die lostOwnershipMethode. Wir drucken einfach eine Nachricht auf der Java-Konsole.

Zeile 6: Erstellen Sie ein ImageSelectionObjekt basierend auf dem Bild im sourceImageSteuerelement.

Zeile 57: Legen Sie den Inhalt der Zwischenablage mit dem ImageSelectionObjekt fest.

Zeile 66: Den Inhalt der Zwischenablage abrufen.

Zeile 68: Stellen Sie sicher, dass der Inhalt nicht null ist und dass die gesuchte Variante unterstützt wird.

Zeile 71: Holen Sie sich die Daten in der entsprechenden Variante.

Zeile 72: Stellen Sie das destinationImageSteuerelement auf den gerade erhaltenen Inhalt ein.

Zeile 90: Definieren Sie die ImageSelectionKlasse.

Zeile 93: Definieren Sie ein Array von DataFlavoraufgerufen supportedFlavorsmit einem Element ( imageFlavor).

Zeile 102: Erstellen Sie den Bildgeschmack. Der erzeugte Geschmack basiert auf dem java.awt.Imagemit dem Darstellungsnamen "Bild".

Zeilen 111 bis 130: Implementieren Sie die TransferableMethoden.

Zeile 123: Geben Sie mit dieser Methode den Inhalt der Zwischenablage zurück.

Zeile 125: Überprüfen Sie den Geschmack. Wenn die angeforderte Variante unterstützt wird, wird das Bildobjekt zurückgegeben. Andernfalls wird eine Ausnahme ausgelöst.

In Listing 1 haben wir die Standarddatenvariante ( StringSelection) verwendet, um Text an die Systemzwischenablage zu senden. In Listing 2 haben wir unsere eigene Datenvariante implementiert java.awt.Image.