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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

DragAndDrop a shape with JavaFX


Sujet :

JavaFX

  1. #1
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut DragAndDrop a shape with JavaFX
    Bonjour,

    J'ai plus une question à vous posez qu'un problème à résoudre. A vrai dire, je chercher à DragAndDrop un shape depuis une toolbar vers un Canva.
    J'ai vu qu'il existe des eventsHandlers pour DragAndDrop. Le soucis, c'est que je ne sais pas dans quel autre je les fais.
    J'aimerai lorsque je clique, copié le Shape, puis tant que je ne relache pas, je ne fais rien. Et lorsque je le Drop, j'aimerai le Shape à l'endroit où j'ai relaché la souris.

    Est-ce que cela suffit ?

    1. setOnDragDetected() //Lorsque je clique enfoncé et que je commence à déplacer
    2. setOnDragOver() //Lorsque je relache

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Bonjour,
    il faut bien comprendre qu'il existe 2 type de DnD et que les gens les confondent tous les 2 très souvent alors qu'il ne s'agit pas du tout de la même chose en fait :
    • Déplacer et bouger une forme dans un même espace (le composant parent) - Déplacer un rectangle à la souris en JavaFX ou encore Proper way to move a JavaFx8 node around sur StackOverflow
    • Déplacer une forme qui pourra être relâchée dans un autre espace de l'application (un autre composant parent), ou même une autre application (pas forcément écrite en Java) ou même sur le bureau et que l'opération pourra éventuellement exporter cette forme dans d'autre types de données alternatives telles que des images ou du texte. Cette pratique reposer en fait sur l'utilisation du Presse-Papier (Clipboard) de l'application ou système. En fait c'est ça le vrai DnD tel qu'on en parle dans les API AWT ou JavaFX. - FAQ - Drag'n Drop
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Oh, je vois ! Effectivement, je ne le savais pas. Le cas n°2 semble plus correspondre à mon problème, vu que je passe d'une ToolBar vers un Canva, (donc 2 composants différents).
    Merci de l'information !

    Edit : Alors.. J'ai essayé de le faire, il détected bien le DragAndDrop, mais il ne prend pas en compte le DragAndDropOver. Rien ne se passe, il n'exécute même pas le handler associé. J'ai pourtant bien mon shape qui est dans ma Toolbar, que je souhaite déplacé dans un canva, sachant que mon canva et ma toolbar sont tous les deux dans un BorderPane.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Pourrais-tu nous montrer ce que tu as tenté de faire STP ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Ah, mon code ne s'est effectivement pas affiché :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    public class DragAndDropEventHandler extends EventHandlerFX {
    	private ArrayList<EventHandlerFX> handlers;
     
    	DragAndDropEventHandler(ControllerFX controller) {
    		super(controller);
    		// TODO Auto-generated constructor stub
    	}
     
    	/* Aide : https://java.developpez.com/faq/javafx?page=Drag-n-Drop */
     
    	//On dit à l'objet qu'on va le DragAndDrop. il permet juste de le déclencher. Fonction de départ
    	//Elle doit être donnée à a tous les shapes de la ToolBar
        EventHandler<MouseEvent>setOnDragDetected = new EventHandler<MouseEvent>() {
        	@Override
        	public void handle(MouseEvent me) {
        		System.out.println("DnD detecté."); 
        		Shape shapeFX = (Shape)me.getSource();
        		final Dragboard dragBroard = shapeFX.startDragAndDrop(TransferMode.COPY_OR_MOVE);
     
        		//On récupère la position du shape dans le repère de la Toolbar
    			double x = controller.getView().getShapePositionXInToolBar(shapeFX);
    			double y = controller.getView().getShapePositionYInToolBar(shapeFX);
    			System.out.println("Value of x : " + x);
    			System.out.println("Value of y : " + y);
     
     
    			ArrayList<Shape> shapes = controller.getView().getShapeInToolBar();
    			double shapeX, shapeY; 
    			for(int i = 0 ; i < shapes.size(); i++) {
    				shapeX = controller.getView().getShapePositionXInToolBar(shapes.get(i));
    				shapeY = controller.getView().getShapePositionYInToolBar(shapes.get(i));
    				if(shapeX == x && shapeY == y) {
    					controller.getFormInToolBar().get(i).setPosition(new Position(x, y));
    				}
    			}
     
    			//On copie la forme que l'on va déplacer.
    			for(Form form : controller.getFormInToolBar()) {
    				if(form.getPosition().getX() == x && form.getPosition().getY() == y) {
    					Form formCopy = form.clone();
    					controller.getFormInCenter().add(formCopy);
    				}
    			}
     
             }
        };
     
        // Permet au canva d'accepter and DragAndDrop
        // A donné au Canva
        EventHandler<DragEvent> setOnDragOver = new EventHandler <DragEvent>(){
    		@Override
    		public void handle(DragEvent dragEvent) {
    			System.out.println("SetOnDragOver : Canva Accepte"); 
    			final Dragboard dragBroard = dragEvent.getDragboard();
    			dragEvent.acceptTransferModes(TransferMode.COPY); 	 
    			dragEvent.consume();  
    		}
     
        };
     
        /* Ce qu'il se passe sur le noeud de destination quand on a fini */
        //A donné au canva
        EventHandler<DragEvent> setOnDragDropped = new EventHandler <DragEvent>() {
     
    		@Override
    		public void handle(DragEvent dragEvent) {	
    			System.out.println("On relache le tout !"); 
    			double x = dragEvent.getSceneX();
    			double y = dragEvent.getSceneY();
     
    			int formSize = controller.getFormInCenter().size();
    			controller.getFormInCenter().get(formSize -1).setPosition(new Position(x,y));
    			DrawerShape drawer = controller.getFormInCenter().get(formSize -1).createShapeDrawer(controller.getView());
    			drawer.drawShapeInCenter();	
    			dragEvent.consume();  
    		}
     
        };
     
        //A donné à tous les nodes de ToolBar
        EventHandler<DragEvent> setOnDragDone = new EventHandler <DragEvent>(){
    		@Override
    		public void handle(DragEvent dragEvent) {
    			System.out.println("On a fini !"); 
    			if (dragEvent.getTransferMode() == TransferMode.MOVE) { 
    		        // Faire ce qui est nécessaire pour retirer la source ou la donnée. 
    		    } 
    		    dragEvent.consume();   
    		}
     
        };
     
        @Override
    	public void registerEventHandler() {
        	controller.getView().addRegisterOnDragDetected(setOnDragDetected);
        	controller.getView().addRegisterOnDragOver(setOnDragOver);
        	controller.getView().addRegisterSetOnDragDropped(setOnDragDropped);
        	controller.getView().addRegisterSetOnDragDone(setOnDragDone);
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    package view;
     
    import java.util.ArrayList;
     
    import javafx.geometry.Bounds;
    import javafx.geometry.Orientation;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ToolBar;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.Pane;
    import javafx.scene.shape.Shape;
    import javafx.event.EventHandler;
    import javafx.scene.input.DragEvent;
    import javafx.scene.input.MouseEvent;
     
    public class ViewFX implements View{
     
    	private Scene scene;
    	private Pane centralCanva;
    	private BorderPane root;
     
    	/* Toolbar du haut et du côté */
    	private ToolBar shapeToolBar;
    	private ToolBar menuToolBar;
     
     
    	/* Bouton pour la toolbar du haut */
    	private Button save;
    	private Button load;
    	private Button redo;
    	private Button undo;
     
    	/* contient les shapes de JavaFX. */
    	private ArrayList<Shape> shapeInToolBar;
    	private ArrayList<Shape> shapeInCenter;
     
     
    	public ViewFX() {
    		this.centralCanva = new Pane();
    		this.root = new BorderPane();
    		this.shapeToolBar = new ToolBar();
    		this.menuToolBar = new ToolBar();
    		this.save = new Button("Save");
    		this.load = new Button("Load");
    		this.redo = new Button("Redo");
    		this.undo = new Button("Undo");
    		this.scene = new Scene(root,900,1000);
     
    		this.shapeInCenter = new ArrayList<Shape>();
    		this.shapeInToolBar = new ArrayList<Shape>();
    	}
     
    	public Scene getScene() {
    		return scene;
    	}
     
    	public Pane getCentralCanva() {
    		return this.centralCanva;
    	}
     
    	@Override
    	public void createMenuToolBar() {
    		this.menuToolBar.getItems().add(save);
    		this.menuToolBar.getItems().add(load);
    		this.menuToolBar.getItems().add(undo);
    		this.menuToolBar.getItems().add(redo);
     
    	}
     
    	@Override
    	public void createFormToolBar() {
    		this.shapeToolBar.setOrientation(Orientation.VERTICAL);		
    	}
     
    	@Override
    	public void addToolBars() {
    		this.root.setTop(menuToolBar);
    		this.root.setLeft(shapeToolBar);
    	}
     
     
    	@Override
    	public void addCanvaCenter() {
    		this.root.setCenter(centralCanva);
    	}
     
    	public ToolBar getToolBar() {
    		return this.shapeToolBar;
    	}
     
    	public BorderPane getRoot() {
    		return this.root;
    	}
     
    	public ArrayList<Shape> getShapeInToolBar() {
    		return shapeInToolBar;
    	}
     
    	public ArrayList<Shape> getShapeInCenter() {
    		return shapeInCenter;
    	}
     
    	//On utilise ses deux méthodes pour déterminer la position d'un shape en fonction de sa position dans 
    	//le node Toolbar et non par rapport à l'ensemble de l'image
    	public double getShapePositionXInToolBar(Shape shape) {
    		Bounds boundsInScene = shape.localToScene(shape.getBoundsInLocal());
    		return boundsInScene.getMinX();
    	}
     
    	public double getShapePositionYInToolBar(Shape shape) {
    		Bounds boundsInScene = shape.localToScene(shape.getBoundsInLocal());
    		return boundsInScene.getMinY();
    	}
     
     
    	//On ajoute les registering des Events Handler pour chaque Shape de JavaFX afin qu'il réagisse aux intéractions et qu'il les traite correctement
     
    	public void addRegisterOnDragDetected(EventHandler <MouseEvent> event) {
    		for(Shape shapeFX : shapeInToolBar) {
    			shapeFX.setOnDragDetected(event);
    		}
    		System.out.println("Nb Shape in tool bar :" + shapeInToolBar.size());
    	}
     
    	public void addRegisterOnDragOver(EventHandler <DragEvent> event) {
    		centralCanva.setOnDragOver(event);
    	}
     
    	public void addRegisterSetOnDragDropped(EventHandler <DragEvent> event) {
    		centralCanva.setOnDragDropped(event);
    	}
     
    	public void addRegisterSetOnDragDone(EventHandler <DragEvent> event) {
    		for(Shape shapeFX : shapeInToolBar) {
    			shapeFX.setOnDragDone(event);
    		}
    	}
    }
    Pour un peu plus de vision, voilà l'affichage : Nom : Capture du 2020-03-24 12-02-54.png
Affichages : 1137
Taille : 10,9 Ko

    Comme vous l'aurez compris, j'aimerai pouvoir déposer les rectangles de ma toolBar dans mon "centralCanva". Et par la suite faire l'inverse.
    Les Forms sont une représentation abstraites (non visuel )d'un Shape de JavaFX.

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    C'est bien mais le soucis c'est que quand on utilise une API spéciale ou qu'il manque la moitié des classes ça rend difficile de pouvoir tester la chose par soit-même. D'où l’intérêt de créer des exemples simples, dépouillés du superflus et réutilisables. Ici es-tu bien assuré qu'utiliser un Canvas soit la solution appropriée ? Ca c'est pas infaisable, mais ça rendra le déplacement de la forme dans la zone de dessin ou son retour via DnD sur la barre d'outil bien plus compliquée. En effet ce qui est dessiné sur un Canvas est une surface "morte", elle ne peut réagir à la souris et il faudra faire des calculs supplémentaires pour déterminer où on a cliqué.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package test.dnd.shape;
     
    import java.io.Serializable;
     
    public final class Form implements Serializable {
        private static final long serialVersionUID = 0L;
        Preset preset;
        private Position position = Position.EMPTY;
     
        public Form derive(final Position position) {
            final var result = new Form();
            result.preset = preset;
            result.position = position;
            return result;
        }
     
        public Position getPosition() {
            return position;
        }
     
        enum Preset {CIRCLE, RECTANGLE}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    package test.dnd.shape;
     
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.scene.SnapshotParameters;
    import javafx.scene.canvas.Canvas;
    import javafx.scene.paint.Color;
     
    public final class FormCanvas extends Canvas {
        // Custom rendering.
        private ObservableList<Form> forms = FXCollections.observableArrayList();
     
        public FormCanvas() {
            getForms().addListener((ListChangeListener<Form>) change -> repaint());
        }
     
        // Resizable canvas.
        @Override
        public double maxHeight(double width) {
            return Double.POSITIVE_INFINITY;
        }
     
        @Override
        public double maxWidth(double height) {
            return Double.POSITIVE_INFINITY;
        }
     
        @Override
        public double minWidth(double height) {
            return 1D;
        }
     
        @Override
        public double minHeight(double width) {
            return 1D;
        }
     
        @Override
        public boolean isResizable() {
            return true;
        }
     
        @Override
        public void resize(double v, double v1) {
            setWidth(v);
            setHeight(v1);
            repaint();
        }
     
        public ObservableList<Form> getForms() {
            return forms;
        }
     
        private void repaint() {
            System.out.printf("repaint - %f x %f%n", getWidth(), getHeight());
            final var gc = getGraphicsContext2D();
            gc.clearRect(0, 0, getWidth(), getHeight());
            gc.setStroke(Color.GREEN);
            gc.setLineWidth(5);
            gc.strokeRect(0, 0, getWidth(), getHeight());
            // Should cache forms to avoid re-creating them.
            System.out.println(getForms().size());
            for (final var form : getForms()) {
                final var shape = Forms.shape(form);
                final var position = form.getPosition();
                final var snapshotParameters = new SnapshotParameters();
                snapshotParameters.setFill(Color.TRANSPARENT);
                final var capture = shape.snapshot(snapshotParameters, null);
                gc.drawImage(capture, position.getX(), position.getY());
            }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    package test.dnd.shape;
     
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Rectangle;
    import javafx.scene.shape.Shape;
     
    import java.util.Objects;
     
    public final class Forms {
        public static Form of(final Form.Preset preset) {
            Objects.requireNonNull(preset);
            final var result = new Form();
            result.preset = preset;
            return result;
        }
     
        public static final Shape shape(final Form form) {
            Objects.requireNonNull(form);
            final var shape = switch (form.preset) {
                case CIRCLE -> new Circle(10);
                case RECTANGLE -> new Rectangle(20, 20);
            };
            final var color = switch (form.preset) {
                case CIRCLE -> Color.RED;
                case RECTANGLE -> Color.BLUE;
            };
            shape.setFill(color);
            return shape;
        }
     
        public static String description(final Form form) {
            Objects.requireNonNull(form);
            final var result = switch (form.preset) {
                case CIRCLE -> "Red circle.";
                case RECTANGLE -> "Blue rectangle.";
            };
            return result;
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package test.dnd.shape;
     
    import java.io.Serializable;
     
    public final class Position implements Serializable {
        private static final long serialVersionUID = 0L;
     
        public static final Position EMPTY = new Position(0, 0);
        final double x;
        final double y;
     
        public Position(double x, double y) {
            this.x = x;
            this.y = y;
        }
     
        final double getX() {
            return x;
        }
     
        final double getY() {
            return y;
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    package test.dnd.shape;
     
    import javafx.application.Application;
    import javafx.geometry.Orientation;
    import javafx.scene.Scene;
    import javafx.scene.SnapshotParameters;
    import javafx.scene.control.Button;
    import javafx.scene.control.ToolBar;
    import javafx.scene.input.*;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
     
    import java.util.Arrays;
     
    public final class Main extends Application {
        public static void main(final String... args) {
            launch(args);
        }
     
        @Override
        public void start(final Stage stage) throws Exception {
            final var toolBar = new ToolBar();
            toolBar.setOrientation(Orientation.VERTICAL);
            Arrays.stream(Form.Preset.values())
                    .map(Forms::of)
                    .map(form -> {
                        final var button = new Button();
                        button.setGraphic(Forms.shape(form));
                        button.getProperties().put("form", form);
                        button.setOnDragDetected(this::impl_onDragDetected);
                        return button;
                    })
                    .forEach(toolBar.getItems()::add);
            final var root = new BorderPane();
            root.setLeft(toolBar);
            final var canvas = new FormCanvas();
            canvas.setOnDragOver(this::impl_onDragOver);
            canvas.setOnDragDropped(this::impl_onDragDropped);
            final var centerPane = new StackPane();
            centerPane.setStyle("-fx-border-color: purple; -fx-background-color: cornflowerblue;");
            centerPane.getChildren().add(canvas);
            root.setCenter(centerPane);
            final var scene = new Scene(root);
            stage.setTitle("Test");
            stage.setWidth(600);
            stage.setHeight(600);
            stage.setScene(scene);
            stage.show();
        }
     
        private final void impl_onDragDetected(final MouseEvent event) {
            System.out.println("impl_onDragDetected");
            final var button = (Button) event.getSource();
            final var form = (Form) button.getProperties().get("form");
            final var dragBoard = button.startDragAndDrop(TransferMode.COPY_OR_MOVE);
            final var content = new ClipboardContent();
            var formFormat = DataFormat.lookupMimeType(Form.class.getName());
            formFormat = (formFormat == null) ? new DataFormat(Form.class.getName()) : formFormat;
            content.put(formFormat, form);
            final var shape = Forms.shape(form);
            final var snapshotParameters = new SnapshotParameters();
            snapshotParameters.setFill(Color.TRANSPARENT);
            final var capture = shape.snapshot(snapshotParameters, null);
            content.putImage(capture);
            final var description = Forms.description(form);
            content.putString(description);
            dragBoard.setContent(content);
            event.consume();
        }
     
        private final void impl_onDragOver(final DragEvent event) {
            final var dragBoard = event.getDragboard();
            var formFormat = DataFormat.lookupMimeType(Form.class.getName());
            formFormat = (formFormat == null) ? new DataFormat(Form.class.getName()) : formFormat;
            if (dragBoard.hasContent(formFormat)) {
                event.acceptTransferModes(TransferMode.COPY);
            }
            event.consume();
        }
     
        private final void impl_onDragDropped(final DragEvent event) {
            boolean success = false;
            try {
                final var canvas = (FormCanvas) event.getSource();
                final var dragBoard = event.getDragboard();
                var formFormat = DataFormat.lookupMimeType(Form.class.getName());
                formFormat = (formFormat == null) ? new DataFormat(Form.class.getName()) : formFormat;
                final var form = (Form) dragBoard.getContent(formFormat);
                final var position = new Position(event.getX(), event.getY());
                final var copy = form.derive(position);
                canvas.getForms().add(copy);
                success = true;
            } finally {
                event.setDropCompleted(success);
                event.consume();
            }
        }
    }

    Bon du coup ca m'a permis de voir que j'avais laissé qq erreur d'orthographe dans la FAQ qui ont jamais été relevées.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  7. #7
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Merci de ta réponse !
    Ici es-tu bien assuré qu'utiliser un Canvas soit la solution appropriée ? Ca c'est pas infaisable, mais ça rendra le déplacement de la forme dans la zone de dessin ou son retour via DnD sur la barre d'outil bien plus compliquée. En effet ce qui est dessiné sur un Canvas est une surface "morte", elle ne peut réagir à la souris et il faudra faire des calculs supplémentaires pour déterminer où on a cliqué
    Que puis-je utiliser à la place d'un Canva ? Je pensais que c'était le cas classique à vrai dire.
    De plus, cette partie de code, j'ai du mal à la comprendre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    final var content = new ClipboardContent();
            var formFormat = DataFormat.lookupMimeType(Form.class.getName());
            formFormat = (formFormat == null) ? new DataFormat(Form.class.getName()) : formFormat;
            content.put(formFormat, form);
    Je suis obligé de faire cela pour un shape de javaFX ? J'entends par là, j'ai l'impression qu'on fait une sorte de sérialisation non ? Et qu'on récupère à la fin de l'event, c'est bien cela ?
    Le problème de mon côté, c'est qu'il détecte le DragAndDrop, mais dans mes autres handlers, rien n'est fait. Même pas un print executé.

  8. #8
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Citation Envoyé par LePtitBen Voir le message
    Que puis-je utiliser à la place d'un Canva ? Je pensais que c'était le cas classique à vrai dire.
    N'importe quel Parent.
    Un Canvas ça sert à faire du bitmap et uniquement du bitmap, donc si tu veux continuer à manipuler des Shape et qu'elles soient réactives ben il faut rester dans du scenegraph.


    De plus, cette partie de code, j'ai du mal à la comprendre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    final var content = new ClipboardContent();
            var formFormat = DataFormat.lookupMimeType(Form.class.getName());
            formFormat = (formFormat == null) ? new DataFormat(Form.class.getName()) : formFormat;
            content.put(formFormat, form);
    Je suis obligé de faire cela pour un shape de javaFX ? J'entends par là, j'ai l'impression qu'on fait une sorte de sérialisation non ? Et qu'on récupère à la fin de l'event, c'est bien cela ?
    Le DnD fonctionne uniquement avec des objets sérialisables (une exception est levée si tu tentes de mettre quelque chose de non-sérialisable dans le presse-papier), entre autre car ça te permet de drag and drop des objets vers une autre application Java lancée dans une JVM séparée de la tienne. Or les Shape (comme tous les nœuds d'ailleurs) ne sont pas sérialisables donc on passe par une abstraction qui l'est et qui va nous permettre de re-créer la bonne shape à destination.

    Comme indiqué précédemment, cette méthode permet aussi d'exporter une même donnée sous plusieurs formes, ici nous exportons la donnée en tant que :
    • Form c'est ce qui est utilisé en interne dans notre application.
    • Image ce qui permet aussi d'exporter vers des logiciels susceptibles de recevoir du bitmap. A noter que dans une version récente de JavaFX ça change aussi l'apparence du curseur du DnD pour montrer un appercu de la forme (précédement il fallait invoquer la méthode dragBoard.setDragView()).
    • et sous formes de String pour les applications susceptibles d'en recevoir.



    Le problème de mon côté, c'est qu'il détecte le DragAndDrop, mais dans mes autres handlers, rien n'est fait. Même pas un print executé.
    Peut-être mais en l'état je peux rien tester.
    A noter que durant le dev de mon application de test, je suis tombé sur un bug où des bindings et du layout mis en place pour m'assurer que le Canvas était bien redimensionné quand on change la taille de la fenêtre empêchait une partie de la propagation des événements (je pouvais cliquer sur les boutons mais pas faire de DnD). Donc j'ai du réécrire le Canvas pour le rendre redimensionnable.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  9. #9
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Je pense savoir d'où vient mon problème. Une fois que l'on met un shape dans une Toolbar, j'ai l'impression que l'on ne peut pas intéragir avec lui. D'où le fait que mes évènements que je lui ai associé ne fonctionnent pas. C'est assez embétant d'ailleurs je trouve.

    Edit : L'erreur venait en fin de compte de moi et de la distinction des shapes dans la toolbar et dans la feuille de dessin . J'ai mal assigné l'handler, et du coup ça fonctionne. Merci du coup de main !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. "With PptDoc.Slides(1).Shapes.Paste" ne marche pas
    Par pirhanas dans le forum Excel
    Réponses: 1
    Dernier message: 21/07/2014, 18h13
  2. [XL-2007] "With PptDoc.Slides(5).Shapes.Paste" ne marche pas
    Par pirhanas dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 21/07/2014, 11h43
  3. [VI-2010] how to select Master shape from stencils with C#
    Par Invité dans le forum Visio
    Réponses: 0
    Dernier message: 14/09/2012, 13h17
  4. [Débutant] Utilisation de FOP - Register Fonts with FOP
    Par Johnbob dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 31/01/2004, 00h27
  5. installation php avec option --with-pgsql: marche pô.
    Par phil25 dans le forum Requêtes
    Réponses: 3
    Dernier message: 02/01/2004, 15h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo