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 :

Réaliser un planning en JavaFX


Sujet :

JavaFX

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    148
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 148
    Points : 62
    Points
    62
    Par défaut Réaliser un planning en JavaFX
    Bonjour,

    Je voudrais savoir si c'est possible de faire un planning comme celui de Google ou Outlook en JavaFX?

    Merci

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    148
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 148
    Points : 62
    Points
    62
    Par défaut
    Aucune idée?


  3. #3
    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
    Si mais ça m'arrive aussi de me reposer durant le week-end (ou dans ce cas précis, j'ai essayer de répondre samedi matin mais le net a planté et donc j'ai repoussé a plus tard).

    Il me semble me souvenir que le scheduler de la JavaOne 2012 qui tournait sur Raspberry Pi etait a base de ListView sévèrement customisée avec des CSS.

    Un autre scheduler, quoi que d'apparence assez differente : A JavaFX weekly scheduler

    Ou celui la qui est probablement plus ce que tu cherches : Writing Google Calendar in JavaFX
    Et apparemment celui-la a été integré a JFXtras.
    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

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    148
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 148
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par bouye Voir le message
    Si mais ça m'arrive aussi de me reposer durant le week-end (ou dans ce cas précis, j'ai essayer de répondre samedi matin mais le net a planté et donc j'ai repoussé a plus tard).

    Il me semble me souvenir que le scheduler de la JavaOne 2012 qui tournait sur Raspberry Pi etait a base de ListView sévèrement customisée avec des CSS.

    Un autre scheduler, quoi que d'apparence assez differente : A JavaFX weekly scheduler

    Ou celui la qui est probablement plus ce que tu cherches : Writing Google Calendar in JavaFX
    Et apparemment celui-la a été integré a JFXtras.
    Finalement, j'ai décidé de développer un Planning en Javafx, et j'ai besoin de quelque idée
    au faite je veux réaliser un planning qui permet de savoir le personnel qui sont en congés ou disponible etc
    verticalement j'ai tout le personnel et horizontalement j'ai les jours, et pour une personne je peux faire un drag and drop horizontalement du premier jours au dernier jour avec une couleur
    voici un exemple qui est proche a ce que je veux http://taitems.github.io/jQuery.Gantt/
    donc est que vous pouvez me donner une piste pour commencer? quel contrôls utiliser?

    Merci

  5. #5
    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
    Une TableView je dirais car elle supporte le multicolonnes comme dans l'entête mais avec plein plein plein de Cell customisés et encore plus de CSS pour rendre le trucs similaire à ce qu'on voit dans la capture.
    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

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    148
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 148
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par bouye Voir le message
    Une TableView je dirais car elle supporte le multicolonnes comme dans l'entête mais avec plein plein plein de Cell customisés et encore plus de CSS pour rendre le trucs similaire à ce qu'on voit dans la capture.
    Oui j'ai penser à utiliser un tableView, par contre comment puis-je gérer les drag and drop des cellules, parce que dans un tableView à peine tu clique sur une cellule, toute la ligne est sélectionnée, tu ne peux pas gérer chaque cellule?
    une dernière question, a quoi correspond les cell customisés? t'aura un petit exemple pour cela? (je sui débutant en JavaFx )

    Merci..

  7. #7
    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
    Ok, je pense qu'on peut oublier TableView pour le moment, et ce pour une raison toute bete : bien que ce soit parfait pour les entêtes de colonnes, on ne peut pas actuellement avoir de cellule qui couvre plusieurs colonnes (Jonathan Giles l'avait fait dans sa présentation Hacking TableView -l'audio et la video de la session sont accessibles sur la page- durant la JavaOne l'an dernier il me semble, il est possible que du code soit disponible quelques part* supportant cette fonctionnalité). Il y a aussi le problème qu'il est difficile d’empêcher le réordonnancent des colonnes (on peut bloquer leur taille, empêcher que le contenu soit trié, mais on peut toujours changer l'ordre des colonnes dans la table) sans passer par des bidouilles (rien d'officiel de prévu avant après le JDK 8).

    Donc il te reste comme choix de :
    1. Créer un contrôler perso avec tout ce que ça implique de devoir manuellement faire le layout du contenu, calcul du positionnement des labels, etc. Bonjour la prise de tête.
    2. Utiliser un ou plusieurs GridPane et prier le dieu des layouts pour ne pas avoir trop de bugs de positionnements.


    J'vais eviter le 1) ça serait trop long, voici un court exemple pour le 2) dans lequels j'ai essayér de ne pas avoir de code trop pourri (évidement les GridPane c'est bien quand on utilise du FXML mais c'est affreux quand on doit le coder). En plus, le résultat n'est pas tout a fait correct puisque des lignes blanches et des micro décalages apparaissent je ne sais pas pourquoi (le code a été testé avec JavaFX 2.2.5, si ça se trouve les bugs disparaissent en JavaFX 8 beta).

    Bonne lecture, en espérant que ce ne soit pas trop indigeste...

    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
    package test;
     
    import java.net.URL;
    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.geometry.HPos;
    import javafx.geometry.Pos;
    import javafx.geometry.VPos;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.LabelBuilder;
    import javafx.scene.control.ScrollPane;
    import javafx.scene.control.ScrollPaneBuilder;
    import javafx.scene.control.Slider;
    import javafx.scene.control.SliderBuilder;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.BorderPaneBuilder;
    import javafx.scene.layout.ColumnConstraints;
    import javafx.scene.layout.ColumnConstraintsBuilder;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.GridPaneBuilder;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.RowConstraints;
    import javafx.scene.layout.RowConstraintsBuilder;
    import javafx.stage.Stage;
     
    /**
     *
     * @author fabriceb
     */
    public class Main extends Application {
     
        enum Month {
     
            JANUARY,
            FEBRUARY,
            MARCH,
            APRIL,
            MAY,
            JUNE,
            JULY,
            AUGUST,
            SEPTEMBER,
            OCTOBER,
            NOVEMBER,
            DECEMBER;
        }
        int[] years = {2011, 2012};
        int[] weeks = {4, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4};
        int numberOfWeeks = 53;
     
        enum Step {
     
            SPRINT_0,
            SPRINT_1,
            SPRINT_2,
            RELEASE_STAGE;
        }
        String[][] subSteps = {{"Analysis", "Scoping"}, {"Development", "Showcasing"}, {"Development", "Showcasing"}, {"Training", "Deployment", "Warranty Period"}};
     
        @Override
        public void start(Stage primaryStage) {
            final int cellSide = 25;
            int planningRowNumber = 1;
            for (final Step step : Step.values()) {
                String[] currentSubSteps = subSteps[step.ordinal()];
                int subStepNumber = currentSubSteps.length;
                planningRowNumber += subStepNumber;
            }
            ////////////////////////////////////////////////////////////////////////
            final GridPane calendar = GridPaneBuilder.create().build();//.gridLinesVisible(true).build();
            final int calendarRowNumber = planningRowNumber + 2;
            int calendarColumnNumber = 0;
            for (final int year : years) {
                for (final Month month : Month.values()) {
                    int weeksInMonth = weeks[month.ordinal()];
                    calendarColumnNumber += weeksInMonth;
                }
            }
            for (int calendarColumnIndex = 0; calendarColumnIndex < calendarColumnNumber; calendarColumnIndex++) {
                final int size = cellSide;
                ColumnConstraints columnConstraints = ColumnConstraintsBuilder.create().minWidth(size).prefWidth(size).maxWidth(size).hgrow(Priority.NEVER).halignment(HPos.CENTER).build();
                calendar.getColumnConstraints().add(columnConstraints);
            }
            for (int calendarRowIndex = 0; calendarRowIndex < calendarRowNumber; calendarRowIndex++) {
                final int size = cellSide;
                RowConstraints rowConstraints = RowConstraintsBuilder.create().minHeight(size).prefHeight(size).maxHeight(size).vgrow(Priority.NEVER).valignment(VPos.CENTER).build();
                calendar.getRowConstraints().add(rowConstraints);
            }
            int yearColumn = 0;
            int yearRow = 0;
            int monthRow = 1;
            int weekRow = 2;
            for (final int year : years) {
                final Label yearLabel = LabelBuilder.create().text(String.valueOf(year)).styleClass("planning-cell", "strong-cell").alignment(Pos.CENTER).maxWidth(Integer.MAX_VALUE).build();
                GridPane.setConstraints(yearLabel, yearColumn, yearRow, numberOfWeeks, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
                calendar.getChildren().add(yearLabel);
                int weekOffset = 0;
                // Month.
                int monthColumn = yearColumn;
                for (final Month month : Month.values()) {
                    final int weeksInMonth = weeks[month.ordinal()];
                    final Label monthLabel = LabelBuilder.create().text(String.valueOf(month)).styleClass("planning-cell", "strong-cell").alignment(Pos.CENTER).maxWidth(Integer.MAX_VALUE).build();
                    GridPane.setConstraints(monthLabel, monthColumn, monthRow, weeksInMonth, 1);
                    calendar.getChildren().add(monthLabel);
                    monthColumn += weeksInMonth;
                    // Weeks.
                    for (int weekIndex = 0; weekIndex < weeksInMonth; weekIndex++, weekOffset++) {
                        final int weekColumn = yearColumn + weekOffset;
                        final Label weekLabel = LabelBuilder.create().text(String.valueOf(weekOffset)).styleClass("planning-cell").alignment(Pos.CENTER).maxWidth(Integer.MAX_VALUE).build();
                        GridPane.setConstraints(weekLabel, weekColumn, weekRow, 1, 1);
                        calendar.getChildren().add(weekLabel);
                    }
                }
                yearColumn += numberOfWeeks;
            }
            for (int calendarRowIndex = 3; calendarRowIndex < calendarRowNumber; calendarRowIndex++) {
                for (int calendarColumnIndex = 0; calendarColumnIndex < calendarColumnNumber; calendarColumnIndex++) {
                    final Label cell = LabelBuilder.create().styleClass("planning-cell").prefWidth(cellSide).prefHeight(cellSide).build();
                    GridPane.setConstraints(cell, calendarColumnIndex, calendarRowIndex);
                    calendar.getChildren().add(cell);
                }
            }
            //////////////////////////////////
            final GridPane planning = GridPaneBuilder.create().build();
            for (int planningColumnIndex = 0; planningColumnIndex < 3; planningColumnIndex++) {
                final Priority hgrow = (planningColumnIndex < 2) ? Priority.NEVER : Priority.ALWAYS;
                int size = (planningColumnIndex < 2) ? 100 : -1;
                ColumnConstraints columnConstraints = ColumnConstraintsBuilder.create().minWidth(size).prefWidth(size).maxWidth(size).hgrow(hgrow).halignment(HPos.LEFT).build();
                planning.getColumnConstraints().add(columnConstraints);
            }
            for (int planningRowIndex = 0; planningRowIndex < planningRowNumber; planningRowIndex++) {
                final int size = (planningRowIndex == 0) ? 3 * cellSide : cellSide;
                RowConstraints rowConstraints = RowConstraintsBuilder.create().minHeight(size).prefHeight(size).maxHeight(size).vgrow(Priority.NEVER).valignment(VPos.TOP).build();
                planning.getRowConstraints().add(rowConstraints);
            }
            int agendaRow = 0;
            int agendaColumn = 2;
            final ScrollPane calendarScroll = ScrollPaneBuilder.create().content(calendar).styleClass("planning-scroll").hbarPolicy(ScrollPane.ScrollBarPolicy.NEVER).vbarPolicy(ScrollPane.ScrollBarPolicy.NEVER).build();
            GridPane.setConstraints(calendarScroll, agendaColumn, agendaRow, 1, Integer.MAX_VALUE);
            planning.getChildren().add(calendarScroll);
            int stepColumn = 0;
            int stepRow = 1;
            int subStepColumn = 1;
            int subStepRow = 1;
            for (final Step step : Step.values()) {
                final String[] currentSubSteps = subSteps[step.ordinal()];
                final int subStepNumber = currentSubSteps.length;
                final Label stepLabel = LabelBuilder.create().text(String.valueOf(step)).styleClass("planning-cell", "strong-cell", "first-cell").alignment(Pos.CENTER_LEFT).maxWidth(Integer.MAX_VALUE).build();
                GridPane.setConstraints(stepLabel, stepColumn, stepRow, 1, 1, HPos.LEFT, VPos.TOP, Priority.ALWAYS, Priority.ALWAYS);
                planning.getChildren().add(stepLabel);
                for (int subStepIndex = 0; subStepIndex < subStepNumber; subStepIndex++, subStepRow++) {
                    if (subStepIndex > 0) {
                        final Label fillerLabel = LabelBuilder.create().styleClass("planning-cell", "first-cell").alignment(Pos.CENTER_LEFT).maxWidth(Integer.MAX_VALUE).build();
                        GridPane.setConstraints(fillerLabel, stepColumn, subStepRow, 1, 1, HPos.LEFT, VPos.TOP, Priority.ALWAYS, Priority.ALWAYS);
                        planning.getChildren().add(fillerLabel);
                    }
                    final Label subStepLabel = LabelBuilder.create().text(currentSubSteps[subStepIndex]).styleClass("planning-cell", "last-cell").alignment(Pos.CENTER_LEFT).maxWidth(Integer.MAX_VALUE).build();
                    GridPane.setConstraints(subStepLabel, subStepColumn, subStepRow, 1, 1, HPos.LEFT, VPos.TOP, Priority.ALWAYS, Priority.ALWAYS);
                    planning.getChildren().add(subStepLabel);
                }
                stepRow += subStepNumber;
            }
     
            final Slider slider = SliderBuilder.create().build();
            slider.valueProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
    //                double hMin = calendarScroll.getHmin();
    //                double hMax = calendarScroll.getHmax();
    //                double hValue = calendarScroll.getHvalue();
    //                double vWidth = calendarScroll.getWidth();
    //                double mWidth = calendar.getWidth();
    //                System.out.printf("val %f\tmin %f value %f max %f width %f maxWidth %f", newValue, hMin, hValue, hMax, vWidth, mWidth).println();
                    calendarScroll.setHvalue(newValue.doubleValue()/100d);
                }
            });
            final BorderPane root = BorderPaneBuilder.create().center(planning).bottom(slider).build();
     
     
     
            final Scene scene = new Scene(root);
            URL cssURL = getClass().getResource("Planning.css");
            if (cssURL == null) {
                cssURL = getClass().getResource("Planning.bss");
            }
            if (cssURL != null) {
                scene.getStylesheets().add(cssURL.toExternalForm());
            }
            primaryStage.setTitle("Planning");
            primaryStage.setScene(scene);
            primaryStage.setWidth(600);
            primaryStage.setHeight(500);
            primaryStage.show();
            //
    //        ScenicView.show(scene);
        }
     
        /**
         * The main() method is ignored in correctly deployed JavaFX 
         * application. main() serves only as fallback in case the 
         * application can not be launched through deployment artifacts,
         * e.g., in IDEs with limited FX support. NetBeans ignores main().
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    }
    Le fichier Planning.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
    .root {
        -inner-header-color: rgb(246, 246, 246);
        -outer-header-color: rgb(221, 221, 221);
    }
    .planning-scroll {
        -fx-background-color: transparent;
        -fx-background-insets: 0;
        -fx-padding: 0;
    }
    .planning-scroll:focused {
        -fx-background-color: transparent;
        -fx-background-insets: 0;
    }
    .planning-cell {
        -fx-background-color: -inner-header-color;
        -fx-background-insets: 0;
        -fx-border-color: -outer-header-color;
        -fx-border-width: 0.75;
        -fx-padding: 3;
    }
    .strong-cell {
        -fx-font-weight: bold;
    }
    .first-cell {
        -fx-background-color: -inner-header-color;
        -fx-background-insets: 0;
        -fx-border-color:  -outer-header-color transparent -outer-header-color -outer-header-color;
    }
    .last-cell {
        -fx-background-color: -inner-header-color;
        -fx-background-insets: 0;
        -fx-border-color: -outer-header-color -outer-header-color -outer-header-color transparent;
    }

    Nom : Planning.jpg
Affichages : 3167
Taille : 53,9 Ko

    *EDIT - voir ici aussi.
    Et pour la sélection sur toute la ligne, justement ça peut se résoudre a grand coup de CSS, je pense (tout comme ici j'ai efface la bordure de focus du ScrollPane dans le CSS).
    Le Drag'n Drop s’implémente au niveau du Cell et non pas de la TableView en JavaFX, on fait ça donc de manière locale et non pas globale.
    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

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    148
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 148
    Points : 62
    Points
    62
    Par défaut
    Merci Bouye pour ton exemple, cela m'a beaucoup aidé, par contre j'ai un soucis avec le "drag" des cellules de la grid (depuis un moment je cherche sur internet aucun résultat) je veux cliquer sur une cell puis en maintenant le clique je fais un glissé horizontalement avec une couleur

    vous avez une idée comment puis-je faire ça?

    merci

  9. #9
    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
    Voici un exemple utilisant l'API de Drag, au lieu de l'api MouseEvent.

    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
    public class Main extends Application {
     
        @Override
        public void start(Stage primaryStage) {
            final int columnNumber = 5;
            final int rowNumber = 3;
            final GridPane gridPane = GridPaneBuilder.create().build();
            gridPane.setPrefSize(-1, -1);
            for (int columnIndex = 0; columnIndex < columnNumber; columnIndex++) {
                final ColumnConstraints columnConstraints = ColumnConstraintsBuilder.create().build();
                columnConstraints.setPrefWidth(-1);
                columnConstraints.setHgrow(Priority.ALWAYS);
                gridPane.getColumnConstraints().add(columnConstraints);
            }
            for (int rowIndex = 0; rowIndex < rowNumber; rowIndex++) {
                final RowConstraints rowConstraints = RowConstraintsBuilder.create().build();
                rowConstraints.setPrefHeight(-1);
                rowConstraints.setVgrow(Priority.ALWAYS);
                gridPane.getRowConstraints().add(rowConstraints);
            }
            for (int rowIndex = 0; rowIndex < rowNumber; rowIndex++) {
                final int destinationRow = rowIndex;
                for (int columnIndex = 0; columnIndex < columnNumber; columnIndex++) {
                    final int destinationColumn = columnIndex;
                    final Pane cell = new Pane();
                    cell.setId(String.format("cell_%d_%d", columnIndex, rowIndex));
                    cell.getStyleClass().add("grid-cell");
                    GridPane.setConstraints(cell, columnIndex, rowIndex);
                    gridPane.getChildren().add(cell);
                    // Drag entered.
    //                cell.setOnDragEntered(new EventHandler<DragEvent>() {
    //                    @Override
    //                    public void handle(DragEvent dragEvent) {
    //                    }
    //                });
                    // Drag over.
                    cell.setOnDragOver(new EventHandler<DragEvent>() {
                        @Override
                        public void handle(DragEvent dragEvent) {
                            cell.getStyleClass().remove("drag-destination");
                            final Node source = (Node) dragEvent.getGestureSource();
                            System.out.printf("Over cell %s from %s", cell.getId(), source.getId()).println();
                            if ("record".equals(source.getId())) {
                                cell.getStyleClass().add("drag-destination");
                                dragEvent.acceptTransferModes(TransferMode.MOVE);
                            }
                            dragEvent.consume();
                        }
                    });
                    // Drag exited.
                    cell.setOnDragExited(new EventHandler<DragEvent>() {
                        @Override
                        public void handle(DragEvent dragEvent) {
                            cell.getStyleClass().remove("drag-destination");
                            dragEvent.consume();
                        }
                    });
                    // Drag finished on this cell.
                    cell.setOnDragDropped(new EventHandler<DragEvent>() {
                        @Override
                        public void handle(DragEvent dragEvent) {
                            cell.getStyleClass().remove("drag-destination");
                            final Node source = (Node) dragEvent.getGestureSource();
                            System.out.printf("Drop cell %s from %s", cell.getId(), source.getId()).println();
                            if ("record".equals(source.getId())) {
                                final int sourceColumn = (int)source.getProperties().get("gridpane-column");
                                final int sourceRow = (int)source.getProperties().get("gridpane-row");
                                final int sourceColumnSpan = (int)source.getProperties().get("gridpane-column-span");
                                int targetColumn = destinationColumn;
                                int targetRow = destinationRow;
                                int targetColumnSpan = sourceColumnSpan;
                                final int targetRowSpan = 1;
                                if (targetRow == sourceRow) {
                                    if (destinationColumn >= sourceColumn + sourceColumnSpan) {
                                        targetColumn = sourceColumn;
                                        targetColumnSpan = destinationColumn - sourceColumn + 1;
                                    }  else if (destinationColumn >= sourceColumn && destinationColumn < sourceColumn + sourceColumnSpan) {
                                        targetColumn = destinationColumn;
                                        targetColumnSpan = sourceColumn + sourceColumnSpan - destinationColumn;
                                    }
                                    else {
                                        targetColumn = destinationColumn;
                                        targetColumnSpan = sourceColumn + sourceColumnSpan - destinationColumn;
                                    }
                                }
                                targetColumnSpan = Math.min(targetColumnSpan, columnNumber - targetColumn);
                                GridPane.setConstraints(source, targetColumn, targetRow, targetColumnSpan, targetRowSpan);
                                source.setMouseTransparent(false);
                            }
                            dragEvent.consume();
                        }
                    });
                }
            }
            final Pane record = new Pane();
            record.setId("record");
            record.getStyleClass().add("record");
            GridPane.setConstraints(record, 2, 1, 1, 1);
            // Initiate drag'n drop.
            record.setOnDragDetected(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent mouseEvent) {
                    final Dragboard dragboard = record.startDragAndDrop(TransferMode.MOVE);
                    final ClipboardContent content = new ClipboardContent();
                    content.put(DataFormat.PLAIN_TEXT, "record");
                    dragboard.setContent(content);
                    record.setMouseTransparent(true);
                    mouseEvent.consume();
                }
            });
            //
            gridPane.getChildren().add(record);
            AnchorPane.setTopAnchor(gridPane, 0d);
            AnchorPane.setRightAnchor(gridPane, 0d);
            AnchorPane.setBottomAnchor(gridPane, 0d);
            AnchorPane.setLeftAnchor(gridPane, 0d);
            AnchorPane root = AnchorPaneBuilder.create().children(gridPane).build();
            Scene scene = new Scene(root, 600, 600);
            URL cssURL = getClass().getResource("Main.css");
            scene.getStylesheets().add(cssURL.toExternalForm());
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
            //
    //        ScenicView.show(scene);
        }
     
        /**
         * The main() method is ignored in correctly deployed JavaFX 
         * application. main() serves only as fallback in case the 
         * application can not be launched through deployment artifacts,
         * e.g., in IDEs with limited FX support. NetBeans ignores main().
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    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
    .root {
        -outer-cell: rgb(50, 50, 50);
        -inner-cell: white;
    }
    .grid-cell {
        -fx-background-color: -outer-cell, -inner-cell;
        -fx-background-insets: 0, 0.05em;
    }
    .drag-destination {
        -inner-cell: gray;
    }
    .record {
        -fx-background-color: -outer-cell, lightgreen, green;
        -fx-background-insets: 6, 7, 8;
        -fx-background-radius: 5, 4, 3;
    }

    C'est loin d’être parfait et plusieurs problèmes se posent :
    • Comme on utilise les infos de layout, le code estime que la colonne source, la ligne source ainsi que le span horizontal du record sont toujours celles spécifiées par le layout (pour la ligne ca va mais pour la colonne ça veut dire que c'est toujours la première colonne occupée par le record). Ça peut être gênant quand on veut redimensionner la cellule dans certaines directions de drag vu qu'on ignore de quelle colonne part réellement le drag.
    • Si on sort le drag de la fenêtre et qu'on le relache ailleurs, le record reste transparent a la souris et on ne peut plus rien en faire. J'ai du passer le record en transparent (a la souris) car sinon on ne pouvait plus relâcher le drag sur les cellules qu'il recouvre.


    Une autre direction de recherche qui corrigera peut-etre le problème : le record est tout le temps transparent et en fait la source du drag est la cellule. Quand on initie un drag on cherche dans le grid pane si un record débute (colonne) ou couvre (colonne + span) la cellule actuelle et on initie le drag le cas échéant. Par contre il faudra trouver un autre moyen de passer le record en paramètres car il n'est alors plus l'objet source du drag.

    Enfin une solution a base de MouseEvent avec des calculs de positionnement a mano reste possible mais serait prise de tete je pense vu que les layouts sont de base redimensionnables et qu'on a differents reperes suivant dans quel noeud on se trouve, que les lignes et les colonnes n'ont pas forcement la même taille tout le temps, ni entre elles, etc etc etc
    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

  10. #10
    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
    Comment faire du drag'n drop avec des MouseEvent : http://java-buddy.blogspot.com.au/20...something.html
    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. [TEST] Réaliser un plan de test complet
    Par cladsam dans le forum Test
    Réponses: 16
    Dernier message: 23/11/2017, 21h54
  2. Réponses: 9
    Dernier message: 30/05/2010, 13h07
  3. [PHP 4] Réaliser un planning qui sera exporté en image ou CSV
    Par Mika2008 dans le forum Langage
    Réponses: 2
    Dernier message: 20/07/2009, 12h16
  4. Demande de conseil pour réaliser un planning
    Par massol joel dans le forum Access
    Réponses: 6
    Dernier message: 26/08/2006, 12h09

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