Astuce Java 61: Couper, copier et coller en Java

Cet article vous donnera une bonne compréhension de la façon d'envoyer et d'obtenir des informations à partir du presse-papiers en Java. Vous apprendrez également à gérer les différentes saveurs de données disponibles. Enfin, nous aborderons les multiples personnalités des presse-papiers et la manière dont ils prennent en charge plus d'une saveur de données.

Java propose deux types de presse-papiers: local et système. Les presse - papiers locaux ne sont disponibles qu'à l'intérieur de la machine virtuelle que votre applet ou application exécute. Cependant, contrairement à certains systèmes d'exploitation qui vous limitent à un seul presse-papiers, Java vous permet d'avoir autant de presse-papiers locaux que vous le souhaitez. Accéder à un presse-papiers local particulier est aussi simple que de s'y référer par son nom.

Les presse - papiers système sont directement liés au système d'exploitation pair, ce qui permet à votre application de transférer des informations entre toutes les applications exécutées sous ce système d'exploitation. Un inconvénient de l'utilisation du presse-papiers système est que vous ne pouvez transférer que des données texte. Les autres types d'objets ne sont pas pris en charge par le presse-papiers système. Avec un peu de chance, ce problème sera résolu dans la prochaine version du JDK.

Avant d'aller plus loin, jetons un coup d'œil à toutes les classes impliquées dans la manipulation du presse-papiers. Ces classes, répertoriées dans le tableau ci-dessous, font toutes partie du package java.awt.datatransfer .

Liste de toutes les classes du package java.awt.datatransfer
Nom Type La description
Clipboard Classe Traite de tout ce qui est transférable
ClipboardOwner Interface Chaque classe qui traite du presse-papiers doit implémenter cette interface. Cette interface est utilisée pour notifier lorsque les données initialement placées dans le presse-papiers ont été écrasées
Dataflavor Classe Représente tous les types de données qui sont transférables
StringSelection Classe Un type de transférable fourni avec Java
Transferable Interface Wrapper aux objets transmis au presse-papiers
UnsupportedFlavor Exception Classe Exception levée par transférable pour une saveur de données non prise en charge

En savoir plus sur les classes de presse-papiers

Allons plus loin dans notre exploration du java.awt.datatransferpackage en examinant en détail chaque classe.

La classe Clipboard

La Clipboardclasse est votre lien pour accéder au presse-papiers. Il comprend trois méthodes, qui sont définies dans le tableau suivant:

Classe de presse-papiers
Méthode La description
String getName () Obtenez le nom du presse-papiers
void setContents (Transferable, ClipboardOwner) Définir le contenu du presse-papiers avec l'objet propriétaire
Transferable getContent (Object) Obtenez le contenu du presse-papiers sous la forme d'un objet transférable. L'objet passé en paramètre est le propriétaire

Les trois Clipboardméthodes de classe ci-dessus vous permettent de nommer le presse-papiers, de lui envoyer des informations ou d'en obtenir des informations. Accéder au presse-papiers système ou créer un presse-papiers local est différent et nécessite un peu plus de discussion. Pour accéder au presse-papiers système, attribuez une référence du presse-papiers système à la Clipboardclasse, telle que:

Clipboard clipboard = getToolkit ().getSystemClipboard ();

D'autre part, pour créer un presse-papiers local, il vous suffit de créer un Clipboardobjet avec le nom que vous souhaitez lui attribuer, par exemple:

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

L'accès au presse-papiers système ou la création d'un presse-papiers local est différent mais simple.

L'interface ClipboardOwner

Parce que Java est un langage multiplateforme et que les systèmes d'exploitation se comportent différemment vis-à-vis des presse-papiers, les auteurs du langage Java ont dû trouver un mécanisme pour gérer les différences subtiles. C'est la raison de la présence de l' ClipboardOwnerinterface. Sa seule fonction est d'informer le propriétaire du presse-papiers lorsque ses données sont écrasées par quelqu'un d'autre. Il peut également signaler à une application quand libérer une ressource associée aux données.

Dans une application réelle, la lostOwnershipméthode peut être utilisée pour définir un indicateur qui informe votre application de la disponibilité des données dans le presse-papiers. Microsoft Word, bien qu'il ne soit pas écrit en Java, est un bon exemple de ce mécanisme à l'œuvre dans une application. Chaque fois que vous placez quelque chose dans le presse-papiers dans Word, puis que vous quittez, une boîte de dialogue s'affiche pour vous informer que les données se trouvent dans le presse-papiers. Il vous sera alors demandé si vous souhaitez laisser les données dans le presse-papiers.

L'implémentation de l' ClipboardOwnerinterface est relativement simple car il n'y a qu'une seule méthode à implémenter. Cette méthode obligera votre programme à renoncer à la propriété du presse-papiers.

La classe DataFlavor

La DataFlavorclasse est utilisée pour représenter le type d'un objet. Vous n'êtes pas limité à une seule saveur (ou type) de données par objet. Et, comme nous, vos objets peuvent avoir plusieurs personnalités! Par exemple, une classe d'image peut être représentée sous la forme d'une classe Java ou d'un tableau de bits (GIF, JPEG, etc.). En réalité, une DataFlavorclasse est un wrapper d'un type MIME. La norme MIME est étendue, il n'y a donc pratiquement aucune limite aux données pouvant être transférées dans le presse-papiers. (Une discussion sur la norme MIME sort du cadre de cet article, mais vous pouvez trouver des informations supplémentaires dans la section Ressources.)

À titre d'exemple de saveur de données, vous constaterez que la StringSelectionclasse a deux saveurs basées sur les types MIME. Lors de l'implémentation, il y a "application / x-java-serialized-object" et le second est "text / plain; charset = unicode". En fait, cette implémentation nous indique que nous pouvons récupérer le texte du presse-papiers sous forme de Stringclasse ( application/x-java-serialized-object) ou de texte brut ( text/plain; charset=unicode).

Il existe deux façons de créer un fichier DataFlavor. Tu peux écrire:

public DataFlavor (representationClass, String humanRepresentationName)

Ce constructeur créera une nouvelle saveur de données qui représente une classe Java. Le retourné DataFlavoraura representationClass = representationClasset un mimeType = application/x-java-serialized-object. À titre d'exemple, ce qui suit créerait un DataFlavorpour le java.awt.Button:

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

Maintenant, ce deuxième constructeur

public DataFlavor (String mimeType, String humanRepresentationName)

construira un en DataFlavorutilisant a MimeType. Le retour DataFlavorsera basé sur le MimeType. Si le MimeTypeest application/x-java-serialized-object, le résultat sera le même que si vous appeliez le constructeur précédent. Néanmoins, le retour DataFlavorsera representationClass= InputStream and mimeType =mimeType. À titre d'exemple, l'appel suivant créerait une saveur de texte brut:

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

Le tableau suivant présente les méthodes de la DataFlavorclasse.

Classe DataFlavor
Méthodes La description
boolean equals (DataFlavor) Teste si le DataFlavor fourni est égal au DataFlavor représenté par cette classe
String getHumanPresentableName () Renvoie le nom représentable par l'homme pour le format représenté par ce DataFlavor
void setHumanPresentableName (String) Définir le nom de la représentation humaine pour ce DataFlavor
String getMimeType () Obtenez la chaîne de type MIME représentée par ce DataFlavor
Class getRepresentationClass () Renvoie la classe qui représente cette classe

L'interface transférable

L' Transferableinterface doit être implémentée par toutes les classes que vous souhaitez envoyer dans le presse-papiers, par conséquent la Clipboardclasse ne comprendra que les classes qui ont été encapsulées par l' Transferableinterface. L' Transferableinterface comprend trois méthodes:

Interface transférable
Méthodes La description
DataFlavor getTransferDataFlavor () Renvoie un tableau de DataFlavor qui représente l'objet
boolean isDataFlavorSupported (DataFlavor) Tester si le DataFlavor fourni est pris en charge
Object getTransferData (DataFlavor) Renvoie l'objet représenté par le DataFlavor fourni

Ceci conclut notre visite de toutes les classes impliquées dans la manipulation du presse-papiers. Nous avons vu que pour accéder au presse-papiers, il faut soit créer un Clipboardobjet, soit obtenir une référence au presse-papiers système. Étant donné que le Presse-papiers n'accepte que les objets de type Transferable, l'objet que vous souhaitez envoyer au Presse-papiers doit implémenter cette interface. Enfin, tous les objets du presse-papiers ont des saveurs qui sont représentées par la DataFlavorclasse, qui en réalité est un wrapper pour les types MIME.

Dans les sections suivantes, nous mettrons en pratique ce que nous avons appris.

La recette de l'utilisation du presse-papiers

La façon dont ces différentes classes accèdent au presse-papiers peut prêter à confusion. Heureusement, il existe une recette simple, qui comprend les étapes suivantes:

Étape 1. Créez une classe appelée xxxxSelection . Ici, xxx devrait nommer le type représenté par cette saveur. Par exemple, ImageSelectionserait un bon nom pour une saveur d'image. Cette convention de dénomination n'est bien sûr qu'une suggestion. Je suis la convention d'utilisation établie avec le StringSelectionfourni dans le JDK, mais vous pouvez nommer cette classe comme vous le souhaitez. Il est important de se rappeler que cet objet doit implémenter les interfaces Transferableet ClipboardOwner. Si vous prévoyez de transférer du texte, la StringSelectionclasse doit être utilisée à la place.

Étape 2. Définissez une classe pour accéder au presse-papiers . Pour accéder à un presse - papiers local, utilisez l'appel suivant: Clipboard clipboard = new Clipboard ("name"). Pour accéder au presse - papiers du système d'exploitation par les pairs, utilisez cet appel à la place: Clipboard clipboard = getToolkit ().getSystemClipboard ().

Étape 3. Définissez le contenu du presse-papiers . Pour ce faire, utilisez la setContentméthode de la Clipboardclasse, où le premier paramètre est un objet qui implémente une Transferable( xxxxSelectionclasse créée à l'étape 1) et le deuxième paramètre est une référence à la classe appelant cette méthode.

Étape 4. Récupérez le contenu du presse-papiers . Utilisez la getContentméthode dans la Clipboardclasse. Cette méthode retournera une classe de type Transferable.

Étape 5. Implémentez une «opération de coupe» . Pour ce faire, vous devez effacer manuellement les données une fois qu'elles sont copiées dans le presse-papiers. Java ne fournit aucune implémentation d'une opération de coupe.

Après cette brève visite des classes impliquant la manipulation du presse-papiers, nous suivrons la recette suggérée pour écrire une simple applet qui transfère le texte dans le presse-papiers du système.

Liste 1

Examinons cette applet:

Liste 1

Ce qui suit est une explication des lignes de code spécifiques de la liste 1.

Ligne 9: Définissez la classe applet1pour étendre la Appletclasse et implémenter l' ClipboardOwnerinterface.

Ligne 17: définir un objet de presse-papiers.

Ligne 26: définissez l'objet Presse-papiers sur le Presse-papiers du système d'exploitation homologue.

Lignes 45 à 47: implémentez la seule méthode dans cette interface. Dans cet article, nous n'utilisons pas la lostOwnershipméthode mais imprimons simplement un message sur la console. Vous pouvez expérimenter cette méthode en copiant du texte dans le presse-papiers à l'aide de cette applet, puis en copiant autre chose à partir d'une autre application. Vous devriez voir le message de perte de propriété apparaître dans la console Java, car les données placées dans le presse-papiers (à l'aide de l'applet Java) ont été écrasées par l'autre application.

Ligne 52: Définissez une classe du type StringSelectionqui implémente une saveur de données texte. Nous obtenons alors le contenu du champ de texte source.

Ligne 53:fieldContent définissez le contenu du presse-papiers sur la classe que nous avons définie à la ligne précédente. Notez que nous devons fournir le propriétaire de cette classe, dans ce cas, cette applet.

Ligne 61: Définissez un objet de type Transferablepour recevoir le contenu du presse-papiers.

Ligne 63: Validez deux choses. Tout d'abord, le presse-papiers est-il vide? Deuxièmement, le contenu du presse-papiers a-t-il la bonne saveur? Dans ce cas, nous recherchons un fichier stringFlavor.

Ligne 67: récupère le contenu du presse-papiers dans une variable chaîne. Pour ce faire, nous appelons la getTransferDataméthode avec la saveur requise. Dans ce cas, nous avons besoin d'un DataFlavor.stringFlavortype.

Ligne 69: définissez le contenu du champ de texte de destination sur le contenu du presse-papiers.

Vous pouvez expérimenter cette applet en transférant du texte entre cette applet et une autre applet Java, ou entre une applet Java et un programme natif, comme le Bloc-notes, pour ceux qui exécutent Microsoft Windows.

Liste 2

Dans le deuxième exemple, nous écrirons une applet qui copie une image dans le presse-papiers. L'image implémentera sa propre saveur.

Liste 2

Ce qui suit est une explication des lignes de code spécifiques du Listing 2.

Ligne 27: Créez un objet de presse-papiers qui fait référence à un presse-papiers local.

Ligne 41: réglez le sourImagecontrôle sur Image.gif.

Lignes 44 à 50: implémentez la lostOwnershipméthode. Nous imprimons simplement un message sur la console Java.

Ligne 6: Créez un ImageSelectionobjet basé sur l'image dans le sourceImagecontrôle.

Ligne 57: définissez le contenu du presse-papiers avec l' ImageSelectionobjet.

Ligne 66: Obtenez le contenu du presse-papiers.

Ligne 68: Assurez-vous que le contenu n'est pas nul et que la saveur que nous recherchons est prise en charge.

Ligne 71: Obtenez les données dans la saveur appropriée.

Ligne 72: réglez le destinationImagecontrôle sur le contenu qui vient d'être obtenu.

Ligne 90: définissez la ImageSelectionclasse.

Ligne 93: Définissez un tableau d' DataFlavorappels supportedFlavorsavec un élément ( imageFlavor).

Ligne 102: Créez la saveur de l'image. La saveur créée est basée sur le java.awt.Imageavec le nom de représentation "Image".

Lignes 111 à 130: implémentez les Transferableméthodes.

Ligne 123: retourne le contenu du presse-papiers avec cette méthode.

Ligne 125: Validez la saveur. Si la saveur demandée est prise en charge, l'objet image est renvoyé. Sinon, une exception est levée.

Dans la liste 1, nous avons utilisé la saveur de données par défaut ( StringSelection) pour envoyer du texte au presse-papiers du système. Dans le listing 2, nous sommes allés plus loin en implémentant notre propre saveur de données java.awt.Image.