IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

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�esDrag'n Drop (10)
pr�c�dent sommaire suivant
 

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.

Mis � jour le 15 mars 2015 bouye

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).

Mis � jour le 15 mars 2015 bouye

� 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.

Mis � jour le 15 mars 2015 bouye

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();

Mis � jour le 15 mars 2015 bouye

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.

Mis � jour le 15 mars 2015 bouye

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.

Mis � jour le 15 mars 2015 bouye

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�.

Mis � jour le 15 mars 2015 bouye

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.

Mis � jour le 15 mars 2015 bouye

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.

Mis � jour le 15 mars 2015 bouye

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.

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 � 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.