FAQ JavaFXConsultez toutes les FAQ

Nombre d'auteurs : 4, nombre de questions : 507, dernière mise à jour : 2 novembre 2016  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur le forum JavaFX de http://java.developpez.com ainsi que l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.


SommaireSceneGraphTransfert de données (18)
précédent sommaire suivant
 

Certains nœuds (ex. : les contrôles de saisie de texte) disposent de méthodes prêtes à l'emploi qui permettent de copier et de coller du texte en provenance ou à destination du presse-papier système. Il est cependant possible de récupérer une référence permettant de manipuler directement le presse-papier en invoquant la méthode statique getSystemClipboard() de la classe javafx.scene.input.Clipboard.

Par exemple :

Code Java : Sélectionner tout
final Clipboard clipboard = Clipboard.getSystemClipboard();

Mis à jour le 15 mars 2015 bouye

Pour placer des données sur le presse-papier, vous devez fournir un objet de type Map<javafx.scene.input.DataFormat, Object> en paramètre de la méthode setContent() de l'instance du presse-papier que vous manipulez.

En effet, lorsque vous chargez des données sur le presse-papier, nous ne chargez pas forcement une simple chaine de texte. Vous allez charger des données sous plusieurs représentations exhaustives.

Imaginons que nous voulons charger une image dans le presse-papier. Il est possible de représenter cette donnée sous plusieurs formes :

  • une chaine de caractères décrivant une image - cette information sera utilisée par les logiciels qui ne supportent pas les images (ex. : un éditeur de texte non riche, liseuse pour aveugle) ;
  • l'image elle-même - qui peut dans ce cas être directement collée dans les logiciels qui le supportent (ex. : un éditeur de texte riche, un logiciel de dessin) ;
  • le fichier dans lequel l'image est stockée - ce qui permettrait de créer un lien vers ce fichier dans un document ;
  • N'importe quel autre type d'information qui peut intéresser une sous-partie de notre programme ou un programme externe avec lequel on souhaiterait s'interfacer.


Nous allons stocker toutes ces valeurs dans une table de hachage utilisant des instances de la classe DataFormat en tant que clés.

Par exemple :

Code Java : Sélectionner tout
1
2
3
final Map<DataFormat, Object> content = new Hashmap<>(); 
[...] 
clipboard.setContent(content);

Vous pouvez utiliser votre propre implémentation de Map<DataFormat, Object>, cependant l'API fournit la classe prête à l'emploi javafx.scene.input.ClipboardContent pour cet usage.

Par exemple :

Code Java : Sélectionner tout
1
2
3
final ClipboardContent content = new ClipboardContent(); 
[...] 
clipboard.setContent(content);

Mis à jour le 15 mars 2015 bouye

Si vous utilisez une simple Map<DataFormat, Object>, il vous suffit d'utiliser sa méthode put() avec le type de donnée approprié.

Par exemple :

Code Java : Sélectionner tout
1
2
content.put(DataFormat.PLAIN_TEXT, "Salut le monde !"); 
content.put(DataFormat.IMAGE, monImage);

Si vous utilisez la classe ClipboardContent, celle-ci dispose de méthodes de convenance pour manipuler les types les plus courants :

  • putFiles() - permet de spécifier une instance de List<File> ;
  • putFilesByPath() - permet de spécifier une instance de List<String> (des chemins d’accès vers des fichiers) ;
  • putHtml() - permet de spécifier une chaine de caractères au format HTML ;
  • putImage() - permet de spécifier une instance de la classe javafx.scene.image.Image ;
  • putRtf() - permet de spécifier une chaine de caractères au formant RTF ;
  • putString() - permet de spécifier une chaine de caractères ;
  • putUrl() - permet de spécifier une chaine de caractères contenant une URL.


Par exemple :

Code Java : Sélectionner tout
1
2
content.putString("Salut le monde !"); 
content.putImage(monImage);

La méthode putIfAbsent() de la classe ClipboardContent permet d’insérer une nouvelle valeur pour un type de donnée précis s'il n'existe pas déjà de valeur pour ce type :

Code Java : Sélectionner tout
content.putIfAbsent(DataFormat.PLAIN_TEXT, "Salut le monde !");

Vous pouvez également utiliser des types de données personnalisés pour peu que les données soient dans un format serializable.

Mis à jour le 15 mars 2015 bouye

La classe javafx.scene.input.DataFormat fournit plusieurs types prêts à l'emploi pour l'utilisation de chaines de caractères, d'images, etc. Ces types sont définis en tant que variables statiques dans la classe :

  • DataFormat.FILES - permet de spécifier une liste de fichier ;
  • DataFormat.HTML - permet de spécifier une chaine de caractères au format HTML ;
  • DataFormat.IMAGE - permet de spécifier une image ;
  • DataFormat.PLAIN_TEXT - permet de spécifier une chaine de caractères ;
  • DataFormat.RTF - permet de spécifier une chaine de caractères au format RTF ;
  • DataFormat.URL - permet de spécifier une chaine de caractères contenant une URL.


Cependant, vous pouvez être amené à devoir créer de nouveaux types suivant vos besoins. Pour créer de nouveaux types de données, il suffit de créer une nouvelle instance de la classe DataFormat en lui fournissant un ou plusieurs types MIME ou identifiants.

Par exemple :

Code Java : Sélectionner tout
final DataFormat fmt = new DataFormat("text/foo", "text/bar");

Si un type de donnée existe déjà pour ces types MIME ou identifiants, une exception de type IllegalArgumentException sera levée.

Note : il va de soi que si votre but est de fournir des données dans des applications tierces, il faudra utiliser des types MIME compris par ces applications. De même, il faudra mettre les données dans des structures et formats que ces applications sont capables de comprendre.

Vous pouvez utiliser n'importe quels types de données personnalisés pour peu que les données soient dans un format serializable.

Mis à jour le 15 mars 2015 bouye

Pour savoir si un type de données existe déjà, il suffit d'invoquer la méthode lookupMimeType() de la classe DataFormat. Cette méthode retourne le type enregistré s'il existe, sinon elle retournera la valeur null.

Par exemple :

Code Java : Sélectionner tout
final DataFormat fmt = DataFormat.lookupMimeType("text/foo");

Mis à jour le 15 mars 2015 bouye

Pour savoir quels sont les types des données contenues dans le presse-papier, il suffit d'invoquer la méthode getContentTypes() de l'objet de type Clipboard. Cette méthode retourne une instance de Set<DataFormat> qui contient tous les types des données actuellement disponibles dans le presse-papier.

Par exemple :

Code Java : Sélectionner tout
final Set<DataFormat> available = clipboard.getContentTypes();

Il est également possible de tester individuellement chaque type de donnée en invoquant la méthode hasContent().

Par exemple :

Code Java : Sélectionner tout
1
2
3
if (clipboard.hasContent(DataFormat.RTF)) { 
   [...] 
}

Mis à jour le 15 mars 2015 bouye

Pour récupérer le contenu du presse-papier, il suffit d'invoquer la méthode getContent() de la classe Clipboard en lui passant en paramètre le type de donnée approprié.

Par exemple :

Code Java : Sélectionner tout
final Image monImage = clipboard.getContent(DataFormat.IMAGE);

La classe Clipboard dispose également de plusieurs méthodes de convenance qui permettent directement d’accéder au contenu :

  • getFiles() - retourne une List<File> ;
  • getHtml() - retourne une chaine de caractères au format HTML ;
  • getImage() - retourne une instance de la classe javafx.scene.image.Image ;
  • getRtf() - retourne une chaine de caractères au format RTF ;
  • getString() - retourne une chaine de caractères ;
  • getUrl() - retourne une chaine de caractères contenant une URL.


Par exemple :

Code Java : Sélectionner tout
final Image monImage = clipboard.getImage();

Ces méthodes retournent la valeur null si le type requis n'est pas présent dans le presse-papier.

Mis à jour le 15 mars 2015 bouye

L'API Clipboard n'offre pas le moyen de placer un écouteur qui permettrait de surveiller les changements d’état et de contenu du presse-papier, de manière à activer ou désactiver un bouton (ou un menu ou menu contextuel) « Coller ». Il est cependant assez facile de créer un framework similaire à ce que nous venons de décrire.

Commençons par créer notre bouton :

Code Java : Sélectionner tout
1
2
3
4
5
final Button pasteButton = new Button("Coller"); 
pasteButton.setOnAction(actionEvent -> { 
    final Clipboard clipboard = Clipboard.getSystemClipboard(); 
    System.out.printf("Contenu du presse-papier \"%s\"", clipboard.getString()).println(); 
});

Nous allons créer une valeur observable qui sera à la valeur false quand le presse-papier ne dispose pas de contenu approprié pour notre application. Au contraire, cette propriété passera à la valeur [c]true[/i] quand le presse-papier contient des données qui nous intéressent.

Code Java : Sélectionner tout
final BooleanProperty clipBoardContentValid = new SimpleBooleanProperty(false);

Et nous allons lier la propriété disable du bouton à cette valeur observable :

Code Java : Sélectionner tout
pasteButton.disableProperty().bind(clipBoardContentValid.not());

Maintenant, nous allons créer un timer qui permet de vérifier périodiquement que le presse-papier contient du contenu valide. Pour cela, nous allons utiliser une PauseTransition :

Code Java : Sélectionner tout
1
2
3
4
5
6
final Duration pauseWaitTime = Duration.millis(750); 
final PauseTransition pauseTransition = new PauseTransition(pauseWaitTime); 
pauseTransition.setOnFinished(actionEvent -> { 
    final Clipboard clipboard = Clipboard.getSystemClipboard(); 
    clipBoardContentValid.set(clipboard.hasString() && !clipboard.getString().trim().isEmpty()); 
});

À chaque fin de pause, nous vérifions que le presse-papier contient du contenu valide et nous modifions la valeur de notre valeur observable en conséquence. Évidemment, ici, nous faisons un test simple avec du contenu sous forme de chaines de caractères, mais vous pouvez tout aussi bien faire des tests sur du contenu et des objets plus complexes.

Comme nous allons faire se répéter cette pause de manière infinie, nous allons l'empaqueter dans une SequentialTransition. Nous faisons cela, car si nous faisons boucler la pause indéfiniment, elle n’exécutera jamais son action. Ici, étant donné que la pause est empaquetée dans une autre transition, l'action sera effectuée correctement :

Code Java : Sélectionner tout
1
2
3
final SequentialTransition waitTimer = new SequentialTransition(pauseTransition); 
waitTimer.setCycleCount(SequentialTransition.INDEFINITE); 
waitTimer.play();

Et voilà ! Le bouton s'activera ou se désactivera en fonction de ce que contient le presse-papier !

Mis à jour le 15 mars 2015 bouye

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsables bénévoles de la rubrique Java : Mickael Baron - Robin56 -