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 :

Bug lors du drag and drop d'un label hors de la zone souhaitée


Sujet :

JavaFX

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur chef de projet
    Inscrit en
    Avril 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur chef de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2018
    Messages : 10
    Points : 8
    Points
    8
    Par défaut Bug lors du drag and drop d'un label hors de la zone souhaitée
    Bonjour,

    Je vous sollicite car j'ai un problème que je n'arrive pas à résoudre.
    Mon application JavaFx consiste en un planning de production construit avec l'aide d'un gridPane. Chaque production est représenté par un label s'étendant sur un certain nombre de colonne du gridPane en fonction de sa durée. Là où les choses se compliquent c'est que je souhaite pouvoir bouger ces productions à l'aide d'un drag and drop. Pas de soucis si le drop est réalisé dans le gridPane la production se déplace à l'endroit souhaité. Par contre s'il est relâché hors de celui-ci (zone volontairement non défini comme étant acceptable), le label reste en place visuellement mais n'est plus accessible.
    Je ne comprend vraiment pas se qui se passe, car l'évenement onDragDetected n'est pas initié. Quelqu'un a-t'il déjà eu ce problème et si tel est le cas comment l'avez vous résolu ?
    Par avance je vous remercie pour toutes vos réponses.

  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
    C'est difficile a dire sans voir du code ni savoir comment tu fais. Est-ce que tu pourrais broder sur cet exemple simple pour l'adapter a la manière dont tu procèdes ?

    Code CSS : 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
    .drag-pane {
    /*    -fx-border-color: red; */
    /*    -fx-grid-lines-visible: true;*/
        -fx-padding: 3px;
        -fx-hgap: 1px;
        -fx-vgap: 1px;
    }
    .drag-pane:target {
        -fx-background-color: lightgreen;
    }
    .appointment {
        -fx-alignment: center;
        -fx-background-radius: 7px;
        -fx-background-color: lightgray;
    }
    .one {
        -fx-background-color: tomato;
    }
    .two {
        -fx-background-color: cornflowerblue;
    }
    .three {
        -fx-background-color: lightcoral;
    }
    .four {
        -fx-background-color: limegreen;
    }

    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
    package gridpane.dnd;
     
    import javafx.css.PseudoClass;
    import javafx.scene.control.Label;
    import javafx.scene.input.ClipboardContent;
    import javafx.scene.input.DragEvent;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.input.TransferMode;
    import javafx.scene.layout.ColumnConstraints;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.RowConstraints;
     
    import java.util.Arrays;
    import java.util.Map;
    import java.util.function.Function;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
     
    final class DragPane extends GridPane {
     
        private final int maxCols = 5;
        private final int maxRows = 10;
     
        private final Map<String, Appointment> appointments;
     
        public DragPane() {
            setId("dragPane");
            getStyleClass().add("drag-pane");
            IntStream.range(0, maxCols)
                    .mapToObj(ColumnConstraints::new)
                    .forEach(constraints -> {
                        constraints.setHgrow(Priority.ALWAYS);
                        constraints.setFillWidth(true);
                        constraints.setMinWidth(75);
                        constraints.setMaxWidth(Double.MAX_VALUE);
                        getColumnConstraints().add(constraints);
                    });
            IntStream.range(0, maxRows)
                    .mapToObj(RowConstraints::new)
                    .forEach(constraints -> {
                        constraints.setVgrow(Priority.ALWAYS);
                        constraints.setFillHeight(true);
                        constraints.setMinHeight(35);
                        constraints.setMaxHeight(Double.MAX_VALUE);
                        getRowConstraints().add(constraints);
                    });
            // Drag.
            setOnDragEntered(this::dragEntered_impl);
            setOnDragOver(this::dragOver_impl);
            setOnDragDropped(this::dragDrop_impl);
            setOnDragExited(this::dragExited_impl);
            // Populate.
            final var appointment1 = new Appointment("Test 1");
            appointment1.setId("appointment1");
            appointment1.getStyleClass().add("one");
            setConstraints(appointment1, 0, 0, 3, 1);
            final var appointment2 = new Appointment("Test 2");
            appointment2.setId("appointment2");
            appointment2.getStyleClass().add("two");
            setConstraints(appointment2, 1, 1, 2, 1);
            final var appointment3 = new Appointment("Test 3");
            appointment3.setId("appointment3");
            appointment3.getStyleClass().add("three");
            setConstraints(appointment3, 4, 2, 1, 1);
            final var appointment4 = new Appointment("Test 4");
            appointment4.setId("appointment4");
            appointment4.getStyleClass().add("four");
            setConstraints(appointment4, 3, 3, 2, 1);
            appointments = Arrays.asList(appointment1, appointment2, appointment3, appointment4)
                    .stream()
                    .collect(Collectors.toMap(Appointment::getId, Function.identity()));
            getChildren().setAll(appointment1, appointment2, appointment3, appointment4);
        }
     
        private static final PseudoClass TARGET_PSEUDOCLASS = PseudoClass.getPseudoClass("target");
     
        private void dragEntered_impl(final DragEvent event) {
            if (event.getDragboard().hasString()) {
                pseudoClassStateChanged(TARGET_PSEUDOCLASS, true);
            }
            event.consume();
        }
     
        private void dragOver_impl(final DragEvent event) {
            if (event.getDragboard().hasString()) {
                final var id = event.getDragboard().getString();
                final boolean dragSupported = appointments.containsKey(id);
                if (dragSupported) {
                    event.acceptTransferModes(TransferMode.MOVE);
                }
                final double x = event.getX();
                final double y = event.getY();
            }
            event.consume();
        }
     
        private void dragExited_impl(final DragEvent event) {
            if (event.getDragboard().hasString()) {
                pseudoClassStateChanged(TARGET_PSEUDOCLASS, false);
            }
            event.consume();
        }
     
        private void dragDrop_impl(final DragEvent event) {
            if (event.getDragboard().hasString()) {
                final double x = event.getX();
                final double y = event.getY();
            }
            event.consume();
        }
     
     
        private static final class Appointment extends Label {
            public Appointment(final String text) {
                super(text);
                setId("appointment");
                getStyleClass().add("appointment");
                setMaxWidth(Double.MAX_VALUE);
                setMaxHeight(Double.MAX_VALUE);
                setOnDragDetected(this::dragStart_impl);
            }
     
            private void dragStart_impl(final MouseEvent event) {
                final var dragBoard = startDragAndDrop(TransferMode.MOVE);
                final var content = new ClipboardContent();
                final var snapshot = snapshot(null, null);
                content.putString(getId());
                dragBoard.setContent(content);
                dragBoard.setDragView(snapshot);
                event.consume();
            }
        }
    }
    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
    package gridpane.dnd;
     
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
     
    import java.net.URL;
    import java.util.Optional;
     
    public final class Main extends Application {
        public static void main(final String... args) {
            launch(args);
        }
     
        @Override
        public void start(Stage stage) throws Exception {
            final var dragPane = new DragPane();
            final var scene = new Scene(dragPane);
            Optional.ofNullable(getClass().getResource("test.css"))
                    .stream()
                    .map(URL::toExternalForm)
                    .forEach(scene.getStylesheets()::add);
            stage.setScene(scene);
            stage.setTitle("Test");
            stage.show();
        }
    }
    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
    Futur Membre du Club
    Homme Profil pro
    Ingénieur chef de projet
    Inscrit en
    Avril 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur chef de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2018
    Messages : 10
    Points : 8
    Points
    8
    Par défaut
    Bonjour Bouye,

    Merci pour ta réponse, je vais essayer de m'inspirer de ton code pour résoudre mon problème.
    Je met tout de même ci-dessous mon code, étant développeur débutant j'apprend au travers de ce projet donc je suis preneur de toutes les remarques pouvant m'aider à m'améliorer.

    Main :
    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
    package sample;
     
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.text.Font;
    import javafx.stage.Stage;
    import sample.View.Planning.PlanningProductionController;
     
    import java.time.LocalDate;
    import java.time.Year;
    import java.util.ArrayList;
    import java.util.Arrays;
     
    public class Main extends Application {
     
        private ArrayList<String> listeMachine = new ArrayList<String>(Arrays.asList("B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","CN71","CN72"));
        private Stage primaryStage;
     
        @Override
        public void start(Stage primaryStage) throws Exception{
     
            this.primaryStage = primaryStage;
     
            // Charger la vue du fichier FXML.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(Main.class.getResource("View/Planning/PlanningProduction.fxml"));
            Parent root = loader.load();
            primaryStage.setScene(new Scene(root, 1200, 500));
     
            // Lier la vue au controller
            PlanningProductionController controller = loader.getController();
            controller.setPrimaryStage(primaryStage);
            controller.planningProductionView(Year.now(),listeMachine);
            primaryStage.show();
            controller.setIndexAffichageDate(LocalDate.now());
        }
     
        public Stage getPrimaryStage() {
            return primaryStage;
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    Controller :
    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
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    package sample.View.Planning;
     
    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.fxml.FXML;
     
    import javafx.scene.Node;
    import javafx.scene.control.Label;
    import javafx.scene.control.ScrollBar;
    import javafx.scene.control.ScrollPane;
    import javafx.scene.effect.DropShadow;
    import javafx.scene.input.*;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.util.Duration;
     
    import java.time.LocalDate;
    import java.time.Month;
    import java.time.Year;
    import java.time.format.DateTimeFormatter;
    import java.time.format.TextStyle;
    import java.time.temporal.TemporalField;
    import java.time.temporal.WeekFields;
    import java.util.ArrayList;
    import java.util.Locale;
     
    public class PlanningProductionController {
     
        private final int largeurCellule = 50;
        private final int hauteurCellule = 30;
     
        private Stage primaryStage;
        private Year anneeCourante;
        private ArrayList<String> listeMachine;
        private int nbJourAnnee;
     
        private Month moisCourant;
        private int indexMois = 1;
        private int semaineCourante;
        private int indexSemaine;
        private int indexLigne;
        private Dragboard dragBroard;
        private boolean outScreen = false;
     
        private Timeline scrolltimeline = new Timeline();
        double dragX;
        double dragY;
        private double scrollVelocity = 0;
        private int speedScroll = 10;
        private boolean dropped;
     
        @FXML
        private GridPane grillePlanning;
        @FXML
        private GridPane entetePlanning;
        @FXML
        private GridPane enteteMachine;
        @FXML
        private ScrollPane scrollEntetePlanning;
        @FXML
        private ScrollPane scrollGrillePlanning;
        @FXML
        private ScrollPane scrollEnteteMachine;
        @FXML
        private ScrollBar scrollGeneral;
     
        /**
         * Fonction affichant le planning de production vierge
         *
         * @param anneeCourante
         * @param listemachine
         */
        public void planningProductionView(Year anneeCourante, ArrayList<String> listemachine) {
     
            //------------------------------
            //Initialisation des variables
            //------------------------------
            this.anneeCourante = anneeCourante;
            this.listeMachine = listemachine;
            nbJourAnnee = anneeCourante.length();//nb de jour dans l'année étudiée
     
            //---------------------------------
            //Fonction affichage view planning
            //---------------------------------
            setEntetePlanning(); //affiche l'entete avec toutes les dates en ligne
            setEnteteMachine(); // affiche l'entete avec toutes les machines en colonne
            setGrillePlanning(); // affiche la grille devant accueillir les productions
     
            //------------------------
            //Production pour test
            //------------------------
            setProduction(LocalDate.now(), 1, 5, "B1");
            setProduction(LocalDate.now(), 1, 10, "B6");
     
            //-----------------------------------
            //Listener pour le scroll de la page
            //-----------------------------------
            scrollGrillePlanning.hvalueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    scrollEntetePlanning.setHvalue(new_val.doubleValue());
                }
            });
            scrollEntetePlanning.hvalueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    scrollGrillePlanning.setHvalue(new_val.doubleValue());
                }
            });
            scrollGrillePlanning.vvalueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    scrollEnteteMachine.setVvalue(new_val.doubleValue());
                }
            });
            scrollEnteteMachine.vvalueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    scrollGrillePlanning.setVvalue(new_val.doubleValue());
                }
            });
            scrollGrillePlanning.hvalueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    scrollGeneral.adjustValue(new_val.doubleValue());
                }
            });
            scrollGeneral.valueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    scrollGrillePlanning.setHvalue(new_val.doubleValue() / 100);
                }
            });
     
            grillePlanning.setOnDragExited(dragEvent -> {
                outScreen = true;
            });
            grillePlanning.setOnDragEntered(dragEvent -> {
                outScreen = false;
            });
        }
     
        //------------------------------
        //Affiche l'entete du planning
        //------------------------------
        private void setEntetePlanning() {
     
            for (int i = 1; i <= nbJourAnnee; i++) { //boucle pour passer tout les jours de l'année
                LocalDate jour = anneeCourante.atDay(i); //jour i
     
                //------------Ligne mois-------------
                if (!jour.getMonth().equals(moisCourant)) { //Création du mois si n'est pas déjà présent
                    moisCourant = jour.getMonth(); //Récupère le mois
                    String txtMois = moisCourant.getDisplayName(TextStyle.FULL, Locale.FRANCE) + " " + anneeCourante.toString(); //Définir le nom du mois + annee à afficher
                    Label lbMois = new Label(txtMois); // Crée le label mois
                    lbMois.getStyleClass().add("mois"); // lie la classe css mois au label
                    int lgMois = moisCourant.length(anneeCourante.isLeap()); // calcul la largeur du label
                    lbMois.setPrefSize(largeurCellule * lgMois, hauteurCellule); // défini la dimension du label
                    entetePlanning.add(lbMois, indexMois, 0, lgMois, 1); // ajoute le label à la grille
                    indexMois += lgMois; //index de position du label mois
                }
     
                //-------------Ligne semaine--------------
                TemporalField semaine = WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear(); //Récupère la semaine
                int weekNumber = jour.get(semaine); // Récupère le n° de la semaine
                if (weekNumber != semaineCourante) {
                    semaineCourante = weekNumber;
                    int lgSemaine = 8 - jour.getDayOfWeek().getValue(); // nombre jour dans la semaine
                    indexSemaine += lgSemaine; // index de position de la semaine
                    if (indexSemaine > nbJourAnnee) {
                        lgSemaine = nbJourAnnee - indexSemaine + lgSemaine; // calcul du nbr de jour à afficher pour la dernière semaine de l'année
                    }
                    Label lbSemaine = new Label("S" + String.valueOf(weekNumber)); // Crée le label semaine
                    lbSemaine.setPrefSize(largeurCellule * lgSemaine, hauteurCellule); // Défini la taille du label semaine
                    lbSemaine.getStyleClass().add("semaine"); // Lie la classe css au label semaine
                    entetePlanning.add(lbSemaine, i, 1, lgSemaine, 1); // Ajouter le label semaine à la grille
                }
     
                //----------------Ligne jour -----------------
                String txtJour = jour.format(DateTimeFormatter.ofPattern("dd")) + " " + jour.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.FRANCE);
                Label lbJour = new Label(txtJour);
                lbJour.getStyleClass().add("jour");
                lbJour.setPrefSize(largeurCellule, hauteurCellule);
                entetePlanning.add(lbJour, i, 2);
                if (jour.getDayOfWeek().getValue() == 6 || jour.getDayOfWeek().getValue() == 7) {
                    lbJour.getStyleClass().add("weekend");
                }
            }
        }
     
     
        private void setEnteteMachine() {
            //-----------------Ligne par Machine------------------
            for (String machine : listeMachine) {
                Label lbMachine = new Label(machine);
                lbMachine.setPrefSize(largeurCellule, hauteurCellule);
                lbMachine.getStyleClass().add("machine");
                indexLigne = listeMachine.indexOf(machine) + 3;
                enteteMachine.add(lbMachine, 0, indexLigne);
            }
        }
     
        private void setGrillePlanning() {
            //Crée la grille support à l'ensemble des productions
            for (int i = 1; i <= nbJourAnnee; i++) { //boucle pour passer tout les jours de l'année
                int nbListeMachine = listeMachine.size();
                for (int y = 1; y <= nbListeMachine; y++) {
                    Pane cellule = new Pane();
                    cellule.setPrefSize(largeurCellule, hauteurCellule);
                    if (y % 2 == 0) {
                        cellule.getStyleClass().add("lignePaire");
                    } else {
                        cellule.getStyleClass().add("ligneImpaire");
                    }
                    grillePlanning.add(cellule, i, y);
     
                    cellule.setOnDragOver(dragEvent -> {
                        dragEvent.acceptTransferModes(TransferMode.MOVE);
                        dragEvent.consume();
                    });
     
                    cellule.setOnDragEntered(dragEvent -> {
                        final int destinationColumn = (int) cellule.getProperties().get("gridpane-column");
                        final int destinationRow = (int) cellule.getProperties().get("gridpane-row");
                        afficheDestination(destinationColumn, destinationRow);
                        dragEvent.consume();
                    });
     
                    cellule.setOnDragExited(dragEvent -> {
                        final int destinationColumn = (int) cellule.getProperties().get("gridpane-column");
                        final int destinationRow = (int) cellule.getProperties().get("gridpane-row");
                        cacherDestination(destinationColumn, destinationRow);
                        dragEvent.consume();
                    });
     
                    cellule.setOnDragDropped(dragEvent -> {
                        boolean success = false;
                        try {
                            if (dragEvent.getAcceptedTransferMode() == TransferMode.MOVE) {
                                final Node source = (Node) dragEvent.getGestureSource();
                                final Node destination = (Node) dragEvent.getGestureTarget();
                                final int destinationColumn = (int) destination.getProperties().get("gridpane-column");
                                final int destinationRow = (int) destination.getProperties().get("gridpane-row");
                                final int sourceColumnSpan = (int) source.getProperties().get("gridpane-column-span");
     
                                grillePlanning.getChildren().remove(source);
                                setProduction(LocalDate.ofYearDay(anneeCourante.getValue(), destinationColumn), 1, sourceColumnSpan, listeMachine.get(destinationRow - 1));
     
                                success = true;
     
                                scrolltimeline.stop();
                                dropped = true;
                            }
     
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            dragEvent.setDropCompleted(success);
                            dragEvent.consume();
                        }
                    });
     
                    scrolltimeline.setCycleCount(Timeline.INDEFINITE);
                    scrolltimeline.getKeyFrames().add(new KeyFrame(Duration.millis(20), (ActionEvent) -> {
                        scrollGeneral.setValue(scrollGeneral.getValue() + scrollVelocity);
                    }));
     
                    scrollGrillePlanning.setOnDragExited(dragEvent -> {
                        dragX = dragEvent.getX();
                        dragY = dragEvent.getY();
     
                        if (dragY > 0) {
                            if (dragX >= scrollGrillePlanning.getWidth()) {
                                scrollVelocity = 0.000001 * speedScroll;
                            } else if (dragX < 0) {
                                scrollVelocity = -0.000001 * speedScroll;
                            }
                            if (!dropped) {
                                scrolltimeline.play();
                            }
     
                        }
                    });
                    scrollGrillePlanning.setOnDragEntered(event -> {
                        scrolltimeline.stop();
                        dropped = false;
                    });
                    scrollGrillePlanning.setOnDragDone(event -> {
                        scrolltimeline.stop();
                    });
                    scrollGrillePlanning.setOnScroll((ScrollEvent event) -> {
                        scrolltimeline.stop();
                    });
                }
            }
        }
     
     
        private void setProduction(LocalDate debut, int dureeReglage, int dureeProduction, String machine) {
            //Création  production
            int indexDebut = debut.getDayOfYear();
            int indexMachine = listeMachine.indexOf(machine) + 1;
            int pourcentageReglage = dureeReglage * 100 / dureeProduction;
     
            Label production = new Label("test1");
            production.getStyleClass().add("production");
            production.setPrefSize(largeurCellule * dureeProduction, hauteurCellule);
            production.setStyle("-fx-background-color: linear-gradient(to right, #00FF90, #00FF90 " + pourcentageReglage + "%, #2db3ff " + pourcentageReglage + "%);");
            grillePlanning.add(production, indexDebut, indexMachine, dureeProduction, 1);
     
            production.setOnDragDetected(dragEvent -> {
                dragBroard = production.startDragAndDrop(TransferMode.MOVE);
                production.getStyleClass().add("productionDrag");
     
                // Remlissage du contenu.
                final ClipboardContent content = new ClipboardContent();
                content.put(DataFormat.PLAIN_TEXT, "production");
                dragBroard.setContent(content);
                dragEvent.consume();
            });
     
            production.setOnDragEntered(dragEvent -> {
                production.setMouseTransparent(true);
            });
        }
     
     
        private void afficheDestination(int destinationColumn, int destinationRow) {
            for (Node node : grillePlanning.getChildren()) {
                if (GridPane.getColumnIndex(node) == destinationColumn) {
                    node.getStyleClass().add("colonneDestination");
                }
            }
            enteteMachine.getChildren().get(destinationRow - 1).getStyleClass().add("ligneDestination");
        }
     
     
        private void cacherDestination(int destinationColumn, int destinationRow) {
            for (Node node : grillePlanning.getChildren()) {
                if (GridPane.getColumnIndex(node) == destinationColumn) {
                    node.getStyleClass().remove("colonneDestination");
                }
            }
            enteteMachine.getChildren().get(destinationRow - 1).getStyleClass().remove("ligneDestination");
        }
     
     
        public void setIndexAffichageDate(LocalDate jour) {
            double index = (jour.getDayOfYear() + (primaryStage.getWidth() / 2 / largeurCellule)) * 100 / nbJourAnnee;
            scrollGeneral.setValue(index);
        }
     
        public void setPrimaryStage(Stage primaryStage) {
            this.primaryStage = primaryStage;
        }
     
        @FXML
        private void handleBouton() {
            setIndexAffichageDate(LocalDate.now());
        }
    }
    CSS :
    Code CSS : 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
    *{
        -fx-font-family: Roboto;
    }
    .barBouton {
        -fx-background-color: whitesmoke;
    }
     
    .bouton {
        -fx-background-color: #2b6480;
        -fx-effect: dropshadow(gaussian, grey, 5, 0, 3, 3);
        -fx-text-fill: snow;
    }
    .bouton:hover{
        -fx-effect: dropshadow(gaussian, grey, 5, 0, 2, 2);
        -fx-opacity: 90%;
        -fx-translate-x: 1px;
        -fx-translate-y: 1px;
    }
     
    .mois {
        -fx-background-color: rgba(74, 71, 72, 0.44);
        -fx-font-size: 150%;
        -fx-border-style: solid;
        -fx-border-width: 0.5;
        -fx-border-color: black;
        -fx-alignment: Center;
    }
     
    .weekend {
        -fx-background-color: khaki !important;
    }
     
    .jour {
        -fx-background-color: rgba(74, 71, 72, 0.20);
        -fx-border-style: solid;
        -fx-border-width: 0.5;
        -fx-border-color: black;
        -fx-alignment: Center;
    }
     
    .semaine {
        -fx-border-style: solid;
        -fx-border-width: 0.5;
        -fx-border-color: black;
        -fx-alignment: Center;
    }
     
    .machine {
        -fx-background-color: rgba(74, 71, 72, 0.20);
        -fx-border-style: solid;
        -fx-border-width: 0.5 0 0.5 0;
        -fx-border-color: black;
        -fx-alignment: Center;
    }
     
    .lignePaire {
        -fx-background-color: rgba(74, 71, 72, 0.05);
    }
     
    .ligneImpaire {
        -fx-background-color: rgba(74, 71, 72, 0.01);
    }
     
    .colonneVide {
        -fx-border-style: solid;
        -fx-border-width: 0.5;
        -fx-border-color: black;
    }
     
    .colonneDestination {
        -fx-border-style: solid;
        -fx-border-color: #2b6480;
        -fx-border-width: 0px 0px 0px 2px;
    }
     
    .ligneDestination {
        -fx-background-color: #2b6480;
    }
     
    .production {
        -fx-alignment: Center;
        -fx-border-style: solid;
        -fx-border-width: 1;
        -fx-border-color: black;
    }
     
    .productionDrag, .production:hover {
        -fx-effect: dropshadow(gaussian, grey, 5, 0, 3, 3);
    }

    FXML :
    Code XML : 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
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.ButtonBar?>
    <?import javafx.scene.control.ScrollBar?>
    <?import javafx.scene.control.ScrollPane?>
    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.layout.Pane?>
    <?import javafx.scene.layout.VBox?>
     
    <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" stylesheets="@planning.css" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.View.Planning.PlanningProductionController">
        <top>
            <ButtonBar buttonMinWidth="80.0" prefHeight="40.0" prefWidth="200.0" styleClass="barButton" BorderPane.alignment="TOP_CENTER">
                <buttons>
                    <Button mnemonicParsing="false" onAction="#handleBouton" styleClass="bouton" text="En ce moment" />
                </buttons>
             <padding>
                <Insets right="10.0" />
             </padding>
            </ButtonBar>
        </top>
       <center>
          <VBox prefHeight="200.0" prefWidth="100.0" styleClass="barBouton" BorderPane.alignment="CENTER">
             <children>
                <ScrollPane id="scrollEntetePlanning" fx:id="scrollEntetePlanning" hbarPolicy="NEVER" maxHeight="-Infinity" minHeight="-Infinity" vbarPolicy="NEVER">
                   <content>
                      <GridPane fx:id="entetePlanning" />
                   </content>
                   <VBox.margin>
                      <Insets left="52.0" />
                   </VBox.margin>
                </ScrollPane>
                <HBox prefWidth="600.0">
                   <children>
                        <ScrollPane fx:id="scrollEnteteMachine" hbarPolicy="NEVER" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="52.0" vbarPolicy="NEVER">
                         <content>
                                  <GridPane fx:id="enteteMachine">
                            </GridPane>
                         </content>
                        </ScrollPane>
                      <ScrollPane fx:id="scrollGrillePlanning" hbarPolicy="NEVER" layoutX="10.0" layoutY="10.0" vbarPolicy="NEVER">
                         <content>
                            <GridPane fx:id="grillePlanning" />
                         </content>
                      </ScrollPane>
                   </children>
                </HBox>
                <ScrollBar fx:id="scrollGeneral" />
             </children>
          </VBox>
       </center>
       <right>
          <Pane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
       </right>
    </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
    Pour le moment la seule remarque sérieuse que je peux faire concerne les règles de codage en java : le nom des packages doit être écrit en minuscule.

    Tu peux facilement faire un ajout dans setProduction() pour permettre un aperçu de ton objet lors du déplacement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    production.setOnDragDetected(dragEvent -> {
        [...]
        final var snapshotParameters = new SnapshotParameters();
        snapshotParameters.setFill(Color.TRANSPARENT);
        final var dragView = production.snapshot(snapshotParameters, null);
        dragBroard.setDragView(dragView);
        [...]
    Apres, il y a un bug avec la gestion de la souris (toujours dans setProduction()) car en l’état si on passe par dessus une production lors du dnd, elle ne peut plus être dnd après.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    production.setOnDragEntered(dragEvent -> {
        production.setMouseTransparent(true);
    });
    Ça devrait plutôt être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    production.setOnDragEntered(dragEvent -> {
        production.setMouseTransparent(true);
        dragEvent.consume();
    });
    production.setOnDragExited(dragEvent -> {
        production.setMouseTransparent(false);
        dragEvent.consume();
    });
    MAIS si on fait ainsi, on a parfois droit a un effet clignotant assez désagréable avec le curseur de dnd qui alterne entre accept et refuse lorsqu'on passe par dessus une production en cours de dnd.

    Peut-être quelque chose comme ça qui désactive la souris sur toutes les productions serait peut-être serait mieux ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    cellule.setOnMouseReleased(event -> {
        grillePlanning.getChildren()
            .stream()
            .filter(node -> node.getStyleClass().contains("production"))
            .forEach(node -> node.setMouseTransparent(false));
    });
    [...]
    production.setOnDragDetected(dragEvent -> {
        [...]
        grillePlanning.getChildren()
            .stream()
            .filter(node -> node.getStyleClass().contains("production"))
            .forEach(node -> node.setMouseTransparent(true));
    });
    Bon après ici j'ai juste mis la restauration des events de la souris sur les productions au niveau des cellules; mais je vois que tu as d'autres écouteur de dnd ailleurs, notamment sur le ScrollPane.

    Ceci dit je ne sais même pas si c'est vraiment pertinent de chercher a bloquer l'input de la souris. Généralement on a qu'un seul dispositif de pointage et il n'est donc pas possible de faire 2 dnd en même temps. Donc si on omet le production.setMouseTransparent(true); en fait le programme semble se comporter comme il se doit (a toi de voir).
    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

Discussions similaires

  1. [Delphi XE7] Bug après un drag and drop
    Par airun dans le forum Delphi
    Réponses: 1
    Dernier message: 04/01/2017, 09h34
  2. Drag and drop d'un label dans un rectangle
    Par juniordev dans le forum Débuter
    Réponses: 1
    Dernier message: 12/12/2013, 10h15
  3. [Dojo] Drag and Drop avec seulement un element dans la zone droppable a chaque fois.
    Par zebulon75018 dans le forum Bibliothèques & Frameworks
    Réponses: 1
    Dernier message: 18/08/2009, 15h17
  4. Réponses: 4
    Dernier message: 01/10/2005, 11h03

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