
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.
- Qu'est-ce que le drag'n drop ?
- Comment d�clencher le drag'n drop ?
- Comment recevoir les notifications des �v�nements de drag'n drop ?
- Comment connaitre la source du drag'n drop ?
- Comment connaitre la destination du drag'n drop ?
- Comment valider le fait qu'une destination peut accepter le drag'n drop ?
- Comment r�cup�rer la donn�e dans la destination ?
- Comment fournir une r�action visuelle sur la destination ?
- Comment savoir quand le drag'n drop est termin� ?
- Comment exporter une image vers un logiciel externe ?
Le drag'n drop ou DnD (litt�ralement tirer et l�cher, nomm� en fran�ais cliquer-tirer) est un m�canisme qui permet par une action � la souris ou par un geste tactile d'activer le transfert d'un objet, ou une de ses repr�sentations, vers une autre partie de l'interface graphique, un autre programme (Java ou m�me natif), des �l�ments du syst�me sous-jacent (ex. : le bureau).
Il ne s'agit pas, ici, de vous apprendre comment cliquer sur un n�ud pour le d�placer sur l��cran. Ici, nous verrons comment transf�rer des informations (qui peuvent �tre le n�ud lui-m�me) vers des entit�s int�ress�es pour recevoir de telles informations.
Nous pouvons donc avoir :
- n�ud source → n�ud destination ;
- n�ud source → application externe.
Pour d�clencher le drag'n drop, il faut invoquer la m�thode startDragAndDrop() de la classe Node par exemple, en r�action � une action de la souris sur un n�ud.
La m�thode startDragAndDrop() prend en param�tre une ou plusieurs instances de l��num�ration javafx.scene.input.TransferMode :
- TransferMode.COPY - la source du DnD indique qu'elle sera copi�e dans sa destination ;
- TransferMode.LINK - la source du DnD indique qu'elle sera li�e dans sa destination ;
- TransferMode.MOVE - la source du DnD indique qu'elle sera d�plac�e vers sa destination.
De plus, l��num�ration propose des constantes pr�tes � l'emploi pour un usage dans la m�thode startDragAndDrop() :
- TransferMode.ANY - tableau contenant COPY, LINK et MOVE → tous les modes de transfert sont support�s ;
- TransferMode.COPY_OR_MOVE - tableau contenant COPY et MOVE → le mode LINK n'est pas support� ;
- TransferMode.NONE - tableau vide → aucun mode de transfert n'est support�.
La m�thode startDragAndDrop() retourne un objet de type javafx.scene.input.Dragboard. Cette classe fonctionne de mani�re similaire � la classe Clipboard qui g�re le presse-papier : elle va servir � faire transiter des informations serializable qui peuvent �tre de plusieurs types. Le DnD ne d�marrera pas si le contenu du Dragboard reste vide.
Par exemple, pour lancer le DnD lors d'une action � la souris, il suffit de fournir un �couteur de type EventHandler<MouseEvent> dans la propri�t� onDragDetected d'un n�ud. Ce callback sera invoqu� lorsqu'on clique sur le n�ud et qu'on essaie de le tirer dans une direction. Ce callback n'est pas directement li� au DnD, il permet juste de le d�clencher ; on pourrait tout aussi bien faire quelque chose de similaire avec la gestion tactile.
Code Java : | S�lectionner tout |
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 | public class Main extends Application { @Override public void start(Stage primaryStage) { final Rectangle rectangle = new Rectangle(50, 50, 150, 100); rectangle.setFill(Color.RED); rectangle.setOnDragDetected(mouseEvent -> { System.out.println("DnD detect�."); final Dragboard dragBroard = rectangle.startDragAndDrop(TransferMode.COPY); // Remlissage du contenu. final ClipboardContent content = new ClipboardContent(); // Exporter en tant que texte. content.putString("Un rectangle rouge."); // Exporter en tant que couleur ARGB. DataFormat paintFormat = DataFormat.lookupMimeType(Paint.class.getName()); paintFormat = (paintFormat == null) ? new DataFormat(Paint.class.getName()) : paintFormat; final Color color = (Color) rectangle.getFill(); final int red = (int) (255 * color.getRed()); final int green = (int) (255 * color.getGreen()); final int blue = (int) (255 * color.getBlue()); final int alpha = (int) (255 * color.getOpacity()); final int argb = alpha << 24 | red << 16 | green << 8 | blue << 0; content.put(paintFormat, argb); // Exporter en tant qu'image. final WritableImage capture = rectangle.snapshot(null, null); content.putImage(capture); // dragBroard.setContent(content); mouseEvent.consume(); }); final Pane root = new Pane(); root.getChildren().setAll(rectangle); final Scene scene = new Scene(root, 600, 600); primaryStage.setTitle("Test de DnD"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } |
Si vous cliquez et tirez votre rectangle, le message � DnD d�tect� � sera affich� sur la console. Mais surtout, nous d�marrons le support du DnD en indiquant que notre source de donn�es souhaite �tre copi�e � destination.
Nous avons de plus export� notre rectangle sous diverses formes :
- une chaine de caract�res donnant sa description ;
- sa peinture de remplissage sous forme d'entier
ARGB. Ici, la classe Color de l'API JavaFX n��tant pas serializable, nous ne pouvons pas la placer directement dans le DragBoard ;
- une image du rectangle.
Si vous avez une version r�cente de JavaFX, lorsque vous cliquez et tirez sur votre rectangle, vous apercevrez une version transparente du rectangle qui se d�placera en suivant le curseur de votre souris. Sur des versions plus anciennes, rien ne s'affichera.
Le curseur de votre souris lui-m�me se transformera lorsque vous passez au-dessus d'autres n�uds JavaFX pour indiquer qu'aucun n'accepte le DnD.
Vous pouvez �galement poursuivre le DnD hors des limites de votre application. Si vous rel�chez le bouton de votre souris sur un �diteur de texte (ex. : sous Windows, le bloc-note ou Microsoft Word), la chaine de caract�res � Un rectangle rouge � sera coll�e dans votre document courant. Certains logiciels d��dition bitmap peuvent m�me aller jusqu�� accepter l'image de votre rectangle (ex. : sous Windows, cela fonctionne avec Adobe Photoshop, mais pas avec Paint.NET, Paint ou Inkscape).
� partir du moment o� le drag'n drop s'est d�clench� (voir conditions plus haut), n'importe quel n�ud du SceneGraph, y compris le n�ud source, devient une destination potentielle et peut recevoir des �v�nements de notification en enregistrant des �couteurs de type EventHandler<DragEvent> via les callbacks suivants :
- onDragDropped - le geste de DnD a �t� rel�ch� au-dessus du n�ud (qui devient le n�ud destination) ;
- onDragEntered - le geste de DnD est entr� sur la surface du n�ud ;
- onDragExited - le geste de DnD est sorti de la surface du n�ud ;
- onDragOver - le geste de DnD se trouve au-dessus du n�ud.
Ces callbacks sont invoqu�s sur les cibles potentielles du DnD qui se trouvent sous le curseur de la souris. Ils sont �galement invoqu�s lorsque la source du DnD se trouve �tre � l�ext�rieur de l'application JavaFX. Par exemple, si on initie un cliquer-tirer d'un paragraphe de texte (ex. : dans Microsoft Word ou OpenOffice Writer), il est tout � fait possible de recevoir ces �v�nements si on d�place le curseur au-dessus d'une application JavaFX.
Lorsque le DnD est termin�, la source (s'il s'agit d'une source JavaFX bien s�r) recevra une notification via le callback onDragDone.
Pour connaitre la source du drag'n drop, il suffit d'invoquer la m�thode getGestureSource() de l�objet de type DragEvent pass� en param�tre des callbacks.
Par exemple :
Code Java : | S�lectionner tout |
final Object source = dragEvent.getGestureSource();
Pour connaitre la destination du drag'n drop, il suffit d'invoquer la m�thode getGestureTarget() de l�objet de type DragEvent pass� en param�tre des callbacks plac�s sur le n�ud destination.
Code Java : | S�lectionner tout |
final Object source = dragEvent.getGestureTarget();
Tant que le DnD n'est pas valid�, finalis� ou s'il est annul� (en appuyant sur la touche ECHAP par exemple), cette m�thode retournera la valeur null.
Pour valider le fait qu'un n�ud destination peut accepter un (ou plusieurs) type(s) de donn�es et un (ou plusieurs) mode(s) de transfert, vous devez invoquer la m�thode acceptTransferModes() de la classe DragEvent.
Ajoutons un cercle bleu dans notre exemple :
Code Java : | S�lectionner tout |
1 2 3 | final Circle circle = new Circle(250, 200, 50); circle.setFill(Color.BLUE); root.getChildren().add(circle); |
Pour le moment, quand la souris passe au-dessus du cercle lors du DnD, son curseur indique qu'il n'accepte pas les donn�es que nous essayons de transf�rer.
Nous allons lui fournir un �couteur de type EventHandler<DragEvent> dans le callback onDragOver, ce qui va permettre de changer ce comportement :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | circle.setOnDragOver(dragEvent -> { final Dragboard dragBroard = dragEvent.getDragboard(); DataFormat paintFormat = DataFormat.lookupMimeType(Paint.class.getName()); paintFormat = (paintFormat == null) ? new DataFormat(Paint.class.getName()) : paintFormat; if (dragEvent.getGestureSource() != circle && dragBroard.hasContent(paintFormat)) { // Indique les modes de transfert autoris�s sur cette destination. dragEvent.acceptTransferModes(TransferMode.COPY); } dragEvent.consume(); }); |
Ici, nous avons v�rifi� que la source du DnD n'est pas notre cercle lui-m�me. Puis, nous avons v�rifi� que le DragBoard contient bien une donn�e dans un format qui nous int�resse. Puis, nous avons indiqu� que le cercle supporte les modes de transfert de type COPY.
D�sormais, quand la souris passe au-dessus du cercle lors du DnD, son curseur indique que le cercle accepte les donn�es que nous essayons de transf�rer.
Pour r�cup�rer la donn�e dans la destination, vous devez fournir un �couteur de type EventHandler<DragEvent> dans le callback onDragDroppped du n�ud destination. Ce callback sera invoqu� uniquement lorsque le DnD est rel�ch� au-dessus du n�ud destination et uniquement si ce n�ud a auparavant valid� les types de donn�es et les modes de transfert du DnD.
Par exemple :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | circle.setOnDragDropped(dragEvent -> { boolean success = false; try { final Dragboard dragBroard = dragEvent.getDragboard(); DataFormat paintFormat = DataFormat.lookupMimeType(Paint.class.getName()); paintFormat = (paintFormat == null) ? new DataFormat(Paint.class.getName()) : paintFormat; final int argb = (Integer) dragBroard.getContent(paintFormat); final double opacity = ((argb >> 24) & 0xFF) / 255.0; final int red = (argb >> 16) & 0xFF; final int green = (argb >> 8) & 0xFF; final int blue = (argb >> 0) & 0xFF; final Color fill = Color.rgb(red, green, blue, opacity); circle.setFill(fill); success = true; } catch (Exception ex) { [...] } finally { dragEvent.setDropCompleted(success); dragEvent.consume(); } }); |
Ici, nous r�cup�rons la couleur qui a �t� plac�e dans le DragBoard au tout d�but du DnD et, apr�s d�codage, nous l'affectons en tant que couleur de remplissage de notre cercle. Lorsque le DnD est rel�ch� au-dessus du cercle bleu, ce dernier prend la couleur rouge.
Lorsque l�op�ration est finie, la m�thode setDropCompleted() de la classe DragEvent doit �tre invoqu�e avec le param�tre true pour signifier que le DnD est termin�.
Il est possible de faire que le n�ud destination pr�sente un visuel indiquant si le transfert est valid� ou pas en utilisant ses callbacks onDragEntered et onDragExited. Ces callbacks acceptent des �couteurs de type EventHandler<DragEvent>.
Par exemple :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | circle.setOnDragEntered(dragEvent -> { final Dragboard dragBroard = dragEvent.getDragboard(); DataFormat paintFormat = DataFormat.lookupMimeType(Paint.class.getName()); paintFormat = (paintFormat == null) ? new DataFormat(Paint.class.getName()) : paintFormat; if (dragEvent.getGestureSource() != circle && dragBroard.hasContent(paintFormat)) { circle.setStroke(Color.GREEN); } else { circle.setStroke(Color.ORANGE); } circle.setStrokeWidth(10); dragEvent.consume(); }); circle.setOnDragExited(dragEvent -> { circle.setStroke(null); circle.setStrokeWidth(0); dragEvent.consume(); }); |
Ici, lorsque le geste de notre DnD passe au-dessus du cercle, le n�ud se pare d'une bordure verte ou orange selon que le transfert est valid� ou pas. Lorsque le DnD sort de la surface du n�ud (ou qu'il est activ�), la bordure disparait.
De la m�me mani�re, il est �galement possible d'utiliser des CSS inline, des styles de classe ou des pseudoclasses de mani�re � modifier l'apparence visuelle du n�ud destination en fonction du contenu du DnD.
Si le drag'n drop a �t� d�clench� � partir d'un n�ud SceneGraph, alors le callback onDragDone sera invoqu� sur le n�ud source pour finaliser le transfert lorsque le geste de DnD est rel�ch� sur un n�ud destination ou une application externe. Ce callback accepte des �couteurs de type EventHandler<DragEvent>.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 | source.setOnDragDone(dragEvent -> { if (dragEvent.getTransferMode() == TransferMode.MOVE) { // Faire ce qui est n�cessaire pour retirer la source ou la donn�e. [...] } dragEvent.consume(); }); |
Ce callback est invoqu� m�me si la destination n'accepte pas le DnD, il est donc important de tester le mode de transfert qui a �t� utilis� avant d'agir.
Actuellement, utiliser le type de donn�es DataFormat.IMAGE accompagn� d'une Image au format JavaFX ne permet pas d'importer l'image fournie dans la plupart des logiciels ou dans le syst�me (ex. : durant mes tests, sous Windows, cela ne fonctionne qu'avec Adobe Photoshop).
Il existe cependant une solution qui consiste � exporter l'image JavaFX vers un fichier temporaire en utilisant Swing et ImageIO :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | try { final File tempFile = File.createTempFile(String.format("export-%d", System.currentTimeMillis()), ".png"); System.out.println(tempFile.getAbsolutePath()); try (final OutputStream output = new FileOutputStream(tempFile)) { final BufferedImage swingImage = SwingFXUtils.fromFXImage(fxImage, null); ImageIO.write(swingImage, "png", output); content.putFiles(Arrays.asList(tempFile)); tempFile.deleteOnExit(); } } catch (IOException ex) { Logger.getLogger(TestDnD.class.getName()).log(Level.SEVERE, null, ex); } |
Ici, nous cr�ons un fichier temporaire dans lequel nous exportons au format PNG une image Swing cr��e � partir de notre image JavaFX. Nous pla�ons ensuite l'objet File qui r�f�rence ce fichier dans le contenu � exporter. Ce faisant, la plupart des logiciels de dessin sous Windows peuvent d�sormais ouvrir l'image puisqu'ils essaieront d'utiliser le chemin du fichier re�u lors de l�op�ration de DnD. Il est �galement possible de copier l'image en effectuant un DnD directement vers le bureau de cette mani�re.
Note : cette m�thode ne fonctionnera que sur les syst�mes qui supportent �galement Swing et ImageIO.
Une proc�dure similaire peut �galement �tre d�velopp�e pour exporter du contenu en HTML, RTF, etc. vers les logiciels appropri�s.
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 �aLes 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 � 2025 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.