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 :

Modifier l'apparence d'une forme


Sujet :

JavaFX

  1. #1
    Membre actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut Modifier l'apparence d'une forme
    Bonsoir tout le monde,

    je cherchais depuis peu un moyen pour remplacer mes "Controls" par quelque chose de plus (modifiable), alors j'ai eu l'idée de créer mes propres "Controls" à l'aide des formes "Shapes" et grâce au "css", seulement j'ai un petit souci, il y a des bouts de code qui ne s'appliquent pas aux formes comme dans mon cas les bordures "Borders", plus exactement, lorsque je veux afficher qu'un coté, voici ce que j'ai testé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    -fx-border-color: transparent transparent red transparent;
    ce code fonctionne très bien sur un Layout ou un Control mais pas sur une Shape, donc ma question est : y a t'il un moyen de réaliser ce que je veux faire pour une forme ?

    Merci de bien vouloir m'aider !

  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
    Il faut distinguer deux grande familles de nœuds :
    • Les nœuds basiques : Text, Shape, Rectangle, etc. Ces nœuds n'ont que des propriétés basiques :
      • -fx-fill; pour 1 couleur (ici quand je vais dire couleur ça peut dire couleur ou gradient ou texture) de remplissage.
      • -fx-stroke + quelques sélecteurs CSS liés pour 1 couleur de bordure.
    • Les nœuds construits sur Region : tous les gestionnaires de mise en page et tous les contrôles. Ces nœuds peuvent être décorés de plusieurs façons (dont certaines peuvent être mixées entre elles) :
      • -fx-background-color et sélecteurs CSS liés permet de spécifier 1..n couches de couleurs de fond (opaque, si on spécifie une couleur translucide ou transparente on voit bien sur la couleur de la bordure précédente celle-ci au travers, les couches de couleur sont simplement rendues les unes par dessus les autres dans l'ordre de leur déclaration). La plupart des contrôles de base de l'API (ex: Button, etc.) utilise ce sélecteur pour leur LnF (la bordure de focus, la fausse bordure externe, la fausse bordure interne, la couleur de fond sont en fait toutes spécifiées par ce sélecteur). Pour le décalage entre couches c'est -fx-background-insets.
      • -fx-border-color et sélecteurs CSS liés permet de spécifier 1..n couches de couleurs de bordure qui vient se dessiner par dessus le fond du nœud.
      • -fx-background-image et sélecteurs CSS liés permet de spécifier 1..n couches d'images de fond.
      • -fx-border-image et sélecteurs CSS liés permet de spécifier 1..n couches d'images de bordure. Voir aussi -fx-border-image-slice pour faire du 9-slicing (pas testé pour le moment).
      • -fx-shape et sélecteurs CSS liés permet de spécifier un chemin au format SVG qui remplacera la forme rectangulaire de la région.


    plus d'info sur : https://docs.oracle.com/javase/8/jav...ef.html#region

    Quelques exemples :

    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
    .button1 {
        -fx-background-color: black, lightgray;
        -fx-background-insets: 0px, 1px;
        -fx-background-radius: 5px, 4px;
    }
    .button1:hover {
        -fx-background-color: black, lightgray;
        -fx-background-insets: 0px, 5px 10px 5px 10px;
        -fx-background-radius: 0px, 0px;
        -fx-background-radius: 5px 0px 5px 0px, 4px 0px 4px 0px;
    }
    .button2 {
        -focus-color: transparent;
        -border-color: black;
        -fill-color: lightgray;
        -fx-background-color: -focus-color, -border-color, -fill-color;
        -fx-background-insets: -1.5px, 0px, 1px;
        -fx-background-radius: 6.5px, 5px, 4px;
    }
    .button2:hover {
        -fill-color: white;
    }
    .button2:focused {
        -focus-color: cornflowerblue;
    }
    .button2:pressed {
        -fill-color: gray;
    }
    .banner {
        -fx-background-color: #5AC2DD;
        -fx-background-image: url("SlideHeader-1.png"), url("SlideHeader-2.png");
        -fx-background-position: left, right;
        -fx-background-repeat: no-repeat, no-repeat;
    }
    .star-button {
        -outer-border-color: linear-gradient(from 0% 0% to 100% 100%, goldenrod 0%, darkgoldenrod 100%);
        -inner-border-color: lightgoldenrodyellow;
        /*-fill-color: linear-gradient(from 0% 0% to 100% 100%, lightgoldenrodyellow 0%, yellow 10%, gold 50%, gold 75%, orange 100%);*/
        -fill-color: radial-gradient(center 100% 100%, radius 100%, orange 10%, gold 25%, gold 50%, yellow 80%, lightgoldenrodyellow 100%);
        -fx-shape: "m 330,365.21935 c -6.20565,4.97745 -97.52794,-42.69418 -105.47409,-42.31493 -7.94615,0.37925 -94.31316,56.53157 -100.96465,52.16776 -6.65149,-4.36381 10.46679,-105.9478 7.6506,-113.38785 C 128.39568,254.24429 48.302777,189.4564 50.397583,181.78197 52.49239,174.10753 154.39435,158.9968 160.6,154.01935 c 6.20565,-4.97745 43.07253,-101.170885 51.01868,-101.550136 7.94615,-0.379251 53.80675,91.865796 60.45824,96.229606 6.65149,4.36381 109.52937,9.70089 112.34556,17.14093 2.81618,7.44004 -70.74237,79.56135 -72.83717,87.23579 C 309.4905,260.74997 336.20565,360.2419 330,365.21935 Z";    
        -fx-background-color: -outer-border-color, -inner-border-color, -fill-color;
        -fx-background-insets: 0px, 5px, 10px;
    }
    .star-button:hover {
        -fx-scale-x: 1.2;
        -fx-scale-y: 1.2;
    }
    .star-button:focused {
        -outer-border-color: cornflowerblue;
    }

    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
    package cssregion;
     
    import java.net.URL;
    import java.util.Optional;
    import javafx.animation.RotateTransition;
    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.layout.Region;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.util.Duration;
     
    public class Main extends Application {
     
        @Override
        public void start(Stage primaryStage) {
            final Region button1 = new Region();
            button1.setPrefSize(100, 50);
            button1.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
            button1.getStyleClass().add("button1");
            button1.setFocusTraversable(true);
            button1.setOnMouseClicked(mouseEvent -> button1.requestFocus());
            final Region button2 = new Region();
            button2.setPrefSize(100, 50);
            button2.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
            button2.getStyleClass().add("button2");
            button2.setFocusTraversable(true);
            button2.setOnMouseClicked(mouseEvent -> button2.requestFocus());
            final Region banner = new Region();
            banner.setPrefHeight(50);
            banner.setMaxHeight(Region.USE_PREF_SIZE);
            banner.getStyleClass().add("banner");
            final Region starButton = new Region();
            starButton.setPrefSize(100, 100);
            starButton.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
            starButton.getStyleClass().add("star-button");
            starButton.setFocusTraversable(true);
            starButton.setOnMouseClicked(mouseEvent -> {
                starButton.requestFocus();
                final RotateTransition anim = new RotateTransition(Duration.seconds(1.5), starButton);
                anim.setByAngle(360);
                anim.playFromStart();
            });
            final VBox root = new VBox();
            root.setPadding(new Insets(10));
            root.setSpacing(10);
            root.getChildren().addAll(button1, button2, banner, starButton);
            final Scene scene = new Scene(root, 800, 400);
            final Optional<URL> cssURL = Optional.ofNullable(getClass().getResource("test.css"));
            cssURL.ifPresent(url -> scene.getStylesheets().add(url.toExternalForm()));
            primaryStage.setTitle("Test");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    Nom : Untitled.jpg
Affichages : 4695
Taille : 29,6 Ko

    Ici :
    • Pour la bannière, on a une couleur de fond et deux images (une collée sur le bord gauche et une autre collée sur le bord droit de la forme) quand on étire la bannière, les deux images s’éloignent et font apparaitre la couleur de fond. Comme les images sont des PNG transparents, elles se superposent de manière naturelles entre elles et la couleur de fond.
    • Pour l’étoile, il s'agit bien d'une Region dont on a changé la forme et non pas d'une image bitmap quelconque. La forme SVG est directement du copier/coller de la valeur d de la forme dans Inkscape (Menu File -> XML Editor... -> sélectionner la forme dans l'arborescence pour les détails).


    En faisant quelques tests il y a quelques mois, j'avais vu que -fx-shape et certaines options de répétitions ou de stretch d'images ne fonctionnent pas trop bien ensemble.
    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 actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut
    Bonjour,

    D'abord merci pour ce tutoriel sur les nœuds, (j'ai du chemin à faire pour tout assimiler ), ce que j'ai retenu c'est que les formes sont limités dans la personnalisation contrairement à ce que je croyais par rapport aux contrôles, mais malgré cela j'aimerais si possible savoir s'il y a l'équivalent des "Border" dans les formes autre que les "Stroke" vu que celui-ci n'offre pas grandes choses, la raison c'est que j'aime beaucoup travailler avec les formes, s'il n'y a aucun moyen donc je serais obligé de me tourner vers les Contrôles !

    voici ce que j'essaye de faire (Shape-Thickness(Hide-Side)) :

    Nom : BTN 3D.png
Affichages : 5892
Taille : 8,6 Ko

    Merci bien pour votre aide !

  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
    Ce n'est pas tant que cela soit infaisable avec des Shape mais cela demanderai beaucoup trop de programmation pour peu de résultat. C'est juste beaucoup plus rapide avec des Region :

    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
    .my-button {
        -bottom-border-color: black;
        -top-border-color: linear-gradient(from 0% 0% to 0% 100%, #38528B 10%, black 10%);
        -outer-shadow-color: rgba(0, 0, 0, 0.85);    
        -inner-shadow-color: rgba(255, 255, 255, 0.33);
        -text-shadow-color: black;
        -inner-fill-color: #4061A7;
        -visible-side-color: #1F3052;
        -fx-pref-width: -1;
        -fx-pref-height: -1;
        -fx-background-color: -bottom-border-color, -visible-side-color;
        -fx-background-insets: 0px 0px -7px 0px, 0px 0px -6px 0px;
        -fx-background-radius: 6px, 5px;
        -fx-effect: dropshadow(three-pass-box, -outer-shadow-color, 5, 0, 0, 2);
    }
    .my-button:hover {
        -inner-fill-color: derive(#4061A7, 20%);
    }
    .my-button:pressed {
        -inner-fill-color: derive(#4061A7, -20%);
        -fx-padding: 5px 0px 0px 0px;    
        -fx-background-insets: 10px 0px -2px 0px, 11px 0px -1px 0px;
    }
    .my-button .top {
        -fx-pref-width: -1;
        -fx-pref-height: -1;
        -fx-padding: 3px 10px 7px 10px;
        -fx-effect: innershadow(three-pass-box, -inner-shadow-color, 10, 0, 0, 0);    
        -fx-background-color: -top-border-color, -inner-fill-color;
        -fx-background-insets: 0px, 1px;
        -fx-background-radius: 5px, 4px;
    }
    .my-button .label {
        -fx-text-fill: white;
        -fx-font-size: 1.2em;
        -fx-font-weight: bolder;
        -fx-effect: dropshadow(three-pass-box, -text-shadow-color, 2, 0, 0, -1);
    }

    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
    package cssregion2;
     
    import java.net.URL;
    import java.util.Optional;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.AnchorPane;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    import org.scenicview.ScenicView;
     
    public class Main extends Application {
     
        @Override
        public void start(Stage primaryStage) {
            final StackPane myButton = new StackPane();
            myButton.setId("myButton");
            myButton.getStyleClass().add("my-button");
            myButton.setFocusTraversable(true);
            final StackPane buttonBorder = new StackPane();
            buttonBorder.setId("top");
            buttonBorder.getStyleClass().add("top");
            myButton.getChildren().add(buttonBorder);
            final Label text = new Label("Download");
            buttonBorder.getChildren().add(text);
            final AnchorPane root = new AnchorPane();
            root.getChildren().add(myButton);
            myButton.relocate(50, 50);
            final Scene scene = new Scene(root, 300, 250);
            final Optional<URL> cssURL = Optional.ofNullable(getClass().getResource("test.css"));
            cssURL.ifPresent(url -> scene.getStylesheets().add(url.toExternalForm()));
            primaryStage.setTitle("Test");
            primaryStage.setScene(scene);
            primaryStage.show();
            ScenicView.show(root);
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    J'ai utilisé deux Region ici au lieu de 1 seule car tu as deux effets sur le bouton :
    • Une ombre externe noire sur tout le bouton ;
    • Une ombre interne blanche uniquement sur le dessus du bouton.

    Il n'aurait pas été possible de faire cela avec une seule Region.
    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 actif
    Avatar de tondeurh
    Homme Profil pro
    Responsable interopérabilité Informatique
    Inscrit en
    Juillet 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable interopérabilité Informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2005
    Messages : 8
    Points : 221
    Points
    221
    Billets dans le blog
    22
    Par défaut Custom Control
    Citation Envoyé par guatto Voir le message
    Bonjour,

    D'abord merci pour ce tutoriel sur les nœuds, (j'ai du chemin à faire pour tout assimiler ), ce que j'ai retenu c'est que les formes sont limités dans la personnalisation contrairement à ce que je croyais par rapport aux contrôles, mais malgré cela j'aimerais si possible savoir s'il y a l'équivalent des "Border" dans les formes autre que les "Stroke" vu que celui-ci n'offre pas grandes choses, la raison c'est que j'aime beaucoup travailler avec les formes, s'il n'y a aucun moyen donc je serais obligé de me tourner vers les Contrôles !

    voici ce que j'essaye de faire (Shape-Thickness(Hide-Side)) :

    Nom : BTN 3D.png
Affichages : 5892
Taille : 8,6 Ko

    Merci bien pour votre aide !
    Bonjour,

    Pour réaliser ce type d'éléments, il faut créer un "Custom control" en JavaFX

    Exemple de code assez simple et explicite...

    Programme principal de test
    JfXShapeTest.java

    Code java : 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
     
    package jfxshapetest;
     
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.effect.DropShadow;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
     
    /**
     *
     * @author tondeur-h
     */
    public class JfXShapeTest extends Application {
     
        @Override
        public void start(Stage primaryStage) {
     
             //un Label de Test
            Label lb=new Label();
     
            //un effet de drop Shadow (exagéré, mais c'est pour la demo)
            DropShadow ds = new DropShadow();
            ds.setOffsetY(10.0);
            ds.setOffsetX(10.0);
            ds.setRadius(8.0);
            ds.setColor(Color.BLACK);
     
            //mon custom control (Bouton perso)
            MonBouton btn=new MonBouton("CLIC ICI!",100,50);
            btn.setEffect(ds);
            //texte en blanc
            btn.setLblColor("-fx-text-fill:#FFFFFF;");
     
            // Handle du bouton perso
            btn.setOnMouseClicked((MouseEvent me) -> {
                lb.setText("Mon bouton a été clické!");
                System.out.println("Mon bouton a été clické!");
            });
     
     
            VBox root = new VBox(15);
            root.getChildren().addAll(btn,lb);
     
            Scene scene = new Scene(root, 300, 250);
     
            primaryStage.setTitle("Mon bouton");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    }

    La classe MonBouton qui étant la classe Control (je crée ici un nouveau control JavaFx)
    MonBouton.java

    Code java : 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
     
    package jfxshapetest;
     
    import javafx.scene.control.Control;
     
    public class MonBouton extends Control  {
        private String titre = "";
        MonBoutonSkin skin;
     
     
        public MonBouton(String title,double sizeX, double sizeY) {
            super();
            skin=new MonBoutonSkin(this);
            this.titre = title;
            skin.setText(title);
            skin.setSize(sizeX,sizeY);
             setSkin(skin);
        }
     
        public void setLblColor(String style){
           skin.lbl.setStyle(style);
        }
    }

    Le code source qui permet d'implémenter le skin du bouton (son affichage finalement!)
    MonBoutonSkin.java

    Code java : 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
     
    package jfxshapetest;
     
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javafx.scene.control.Label;
    import javafx.scene.control.Skin;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.CycleMethod;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.shape.HLineTo;
    import javafx.scene.shape.MoveTo;
    import javafx.scene.shape.Path;
    import javafx.scene.shape.QuadCurveTo;
    import javafx.scene.shape.VLineTo;
     
    public class MonBoutonSkin implements Skin<MonBouton> {
        static final double LONG_POINTE = 5;
     
        MonBouton control;
        String text = "";
     
        Group rootNode = new Group();
        Label lbl = null;
        int direction = MyBtnInterface.RIGHT;
        EventHandler retourClient = null;
        double labelWidth;
        double labelHeight;
     
     
        /*******************************
         * Constructeur
         * affecte le control par defaut
         * dessine le controle
         * @param control
         *******************************/
        public MonBoutonSkin(MonBouton control) {
            this.control = control;
            draw();
        }
     
     
    /****************************
     * Retourne l'objet Node du noeud en cours
     * ne doit jamais être null
     * @return
     ****************************/
        @Override
        public Node getNode() {
         if (this.rootNode == null) {
    	    this.rootNode = new Group();
    	    draw();
    	}
    	return this.rootNode;
        }
     
    /*****************
     * ne fait rien dans mon cas
     *****************/
        @Override
        public void dispose() {
     
        }
     
     
    /********************
     * Dessiner le bouton
     ********************/
    private void draw() {
     
    //creer le label du btn
    if ( lbl == null ) lbl = new Label(text);
     
    //taille et position de trnaslation par rapport au layout
    labelWidth=100.0;
    labelHeight=25.0;
    lbl.setTranslateX(10);
    lbl.setTranslateY(3);
     
    // Creer le path des elements du bouton
    Path path = new Path();
    MoveTo startPoint = new MoveTo();
    double x = 0.0f;
    double y = 0.0f;
    double controlX;
    double controlY;
    double height = labelHeight;
    startPoint.setX(x);
    startPoint.setY(y);
     
    HLineTo topLine = new HLineTo();
    x += labelWidth;
    topLine.setX(x);
     
    // Courbe du haut
    controlX = x + LONG_POINTE;
    controlY = y;
    x += 10;
    y = height / 2;
    QuadCurveTo quadCurveTop = new QuadCurveTo();
    quadCurveTop.setX(x);
    quadCurveTop.setY(y);
    quadCurveTop.setControlX(controlX);
    quadCurveTop.setControlY(controlY);
     
    // courbe du bas
    controlX = x - LONG_POINTE;
    x -= 10;
    y = height;
    controlY = y;
    QuadCurveTo quadCurveBott = new QuadCurveTo();
    quadCurveBott.setX(x);
    quadCurveBott.setY(y);
    quadCurveBott.setControlX(controlX);
    quadCurveBott.setControlY(controlY);
     
    HLineTo bottomLine = new HLineTo();
    x -= labelWidth;
    bottomLine.setX(x);
     
    VLineTo endLine = new VLineTo();
    endLine.setY(0);
     
    path.getElements().add(startPoint);
    path.getElements().add(topLine);
    path.getElements().add(quadCurveTop);
    path.getElements().add(quadCurveBott);
    path.getElements().add(bottomLine);
    path.getElements().add(endLine);
     
     
    // Creer un jeu de gradient dans le bouton
    Stop[] stops = new Stop[] {
        new Stop(0.0, Color.DARKSEAGREEN),
        new Stop(1.0, Color.SLATEGREY)
    };
    LinearGradient lg =new LinearGradient( 0, 0, 0, 1, true, CycleMethod.REFLECT, stops);
    path.setFill(lg);
     
    //ajouter les éléments au noeud principal (Group)
    rootNode.getChildren().setAll(path, lbl);
     
    //affecter la capture du clic souris sur ce bouton
    rootNode.setOnMouseClicked((MouseEvent mc) -> {
        if ( retourClient != null )
            retourClient.handle(mc);
            });
        }
     
     
    /**************************
     * Affecter le titre du btn
     * @param text
     ***************************/
        public void setText(String text) {
            this.text = text;
            lbl.setText(text);
     
            // update button
            draw();
        }
     
        /********************
         * Affecter la taille du btn
         * @param X
         * @param Y
         *******************/
        public void setSize(double X, double Y){
            labelWidth=X;
            labelHeight=Y;
        }
     
     
    /*************************
     * Retourne le controle
     * ici l'objet MonBouton
     * @return
     *************************/
    @Override
    public MonBouton getSkinnable() {
        return this.control;
    }
     
    }

    Cela donne un bouton de ce type auquel on peut ajouter des effets (effet d'ombre ici), et appliquer du CSS également (couleur blanche sur le titre du bouton), jouer sur l'opacité avec la méthode setOpacity(double) hérité de la classe Control, ajouter un tooltip avec setToolTip(), et toutes les méthodes applicables à un objet Control (en bref!)

    Nom : 2016-05-25_00h16_42.png
Affichages : 4704
Taille : 17,6 Ko

    Reste plus qu'a adapter la méthode draw() avec des Shapes pour dessiner les contrôles dont tu a besoins.

    Cdlt.

  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
    Sympa tient. Mais Control est a un niveau plus élevé que Region puisqu'il introduit la gestion des Skin.

    Note : dès qu'un contrôle étend la classe Control, pour éviter de hard coder la skin dans la classe, on peut utiliser le sélecteur CCS -fx-skin en indiquant le nom complet de la classe skin. On peut alors surcharger la méthode getUserAgentStylesheet() du contrôle pour retourner une feuille de style par défaut. Cette feuille de style par défaut décrivant l'apparence à minima du contrôle et pointant sur le skin par défaut bien sûr. Cela permet après au programmeur lambda de fournir sa propre skin, si besoin, en la spécifiant via ce sélecteur dans la feuille de style de l'application.

    Hum faudra un jour que je finisse le blog post ou je décrivais comment changer un Slider en un gros bouton rond qui tourne sur lui-même (comme sur une radio ou panneau de contrôle sonore) juste en changeant sa skin.
    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 actif
    Avatar de tondeurh
    Homme Profil pro
    Responsable interopérabilité Informatique
    Inscrit en
    Juillet 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable interopérabilité Informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2005
    Messages : 8
    Points : 221
    Points
    221
    Billets dans le blog
    22
    Par défaut
    Citation Envoyé par bouye Voir le message
    Sympa tient. Mais Control est a un niveau plus élevé que Region puisqu'il introduit la gestion des Skin.

    Note : dès qu'un contrôle étend la classe Control, pour éviter de hard coder la skin dans la classe, on peut utiliser le sélecteur CCS -fx-skin en indiquant le nom complet de la classe skin. On peut alors surcharger la méthode getUserAgentStylesheet() du contrôle pour retourner une feuille de style par défaut. Cette feuille de style par défaut décrivant l'apparence à minima du contrôle et pointant sur le skin par défaut bien sûr. Cela permet après au programmeur lambda de fournir sa propre skin, si besoin, en la spécifiant via ce sélecteur dans la feuille de style de l'application.

    Hum faudra un jour que je finisse le blog post ou je décrivais comment changer un Slider en un gros bouton rond qui tourne sur lui-même (comme sur une radio ou panneau de contrôle sonore) juste en changeant sa skin.
    Oui effectivement, c'est une solution intéressante également surtout pour l'utilisateur qui peut proposer ses propres skin en CSS, curieux de lire ton prochain billet sur ce sujet.

    Cdlt.

  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
    Ah tien justement en regardant le code source de Slider tu peux surcharger la méthode createDefaultSkin() (définie dans Control) pour charger le skin par défaut (ce qui évite de le mettre dans le constructeur comme tu as fais) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override 
    protected Skin<?> createDefaultSkin() {
        return new SliderSkin(this);
    }
    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 actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut
    Bonjour

    la solution est dans le code de "Bouye", merci & à toi aussi "tondeurh". Problème résolu !

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

Discussions similaires

  1. TMemo non apparent sur une Form
    Par Hypollite76 dans le forum Delphi
    Réponses: 6
    Dernier message: 26/07/2007, 13h26
  2. modifier la couleur d'une forme libre
    Par TheRealMike dans le forum Excel
    Réponses: 3
    Dernier message: 25/07/2007, 18h33
  3. Réponses: 1
    Dernier message: 06/05/2007, 10h43
  4. Réponses: 5
    Dernier message: 23/05/2006, 15h25
  5. Comment modifier l'apparence d'un Form ?
    Par [Silk] dans le forum Composants VCL
    Réponses: 3
    Dernier message: 26/07/2005, 13h44

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