Publicité
+ Répondre à la discussion
Page 1 sur 4 1234 DernièreDernière
Affichage des résultats 1 à 20 sur 64
  1. #1
    Responsable Eclipse et JAVA

    Avatar de Mickael Baron
    Homme Profil pro Mickael BARON
    Ingénieur de Recherche en Informatique
    Inscrit en
    juillet 2005
    Messages
    6 942
    Détails du profil
    Informations personnelles :
    Nom : Homme Mickael BARON
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche en Informatique
    Secteur : Service public

    Informations forums :
    Inscription : juillet 2005
    Messages : 6 942
    Points : 34 602
    Points
    34 602

    Par défaut Participez à l'enrichissement de la FAQ JavaFX

    Bonjour,

    Actualité oblige, compte-tenu de l'intérêt de la communauté pour JavaFX, nous ouvrons ce sujet pour vous permettre d'y soumettre les questions récurrentes.

    La même règle s'applique que pour les FAQs déjà existantes : une question s'accompagne obligatoirement d'une réponse (sans quoi votre message sera supprimé).

    La FAQ est en ligne à l'adresse suivante : http://java.developpez.com/faq/javafx/

    Merci aux contributeurs.

  2. #2
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Qq idees de ci de la :

    Dois-je connaître le langage Java ou l’API Java avant de me lancer dans JavaFX ?
    Non, mais cela est fortement recommandé car vous ne pourrez pas aller bien loin uniquement avec l’API JavaFX 1.0. Si vous vous contentez de faire des applications graphiques (similaires à du Flash par exemple), vous pouvez vous contenter de JavaFX uniquement.

    Puis-je appeler directement du Java de puis JavaFX ?
    Oui, c’est même recommandé car l’API JavaFX 1.0 est somme toute assez limitée. Vous devrez donc vous reposer sur les bibliothèques Java existantes pour étendre les possibilités de votre application. Vous avez directement accès à tout ce qui est présent sur le CLASSPATH.

    Tout comme en Java, vous pouvez soit directement indiquer le nom complet (package+nom) de la classe :
    Code :
    1
    2
     
    println(java.lang.System.getProperty("java.version"));
    Soit importer l'intégralité du package :
    Code :
    1
    2
    3
    4
     
    import java.lang.* ;
     
    println(System.getProperty("java.version"));
    Soit importer directement la classe elle-même :
    Code :
    1
    2
    3
    4
     
    import java.lang.System ;
     
    println(System.getProperty("java.version"));
    Comme vous l’aurez remarqué, il est nécessaire d'importer manuellement les classes du package java.lang.

    J’ai créé un design dans un éditeur externe, comment le manipuler dans JavaFX ?
    Vous devez récupérer la JavaFX Production Suite qui est disponible sur http://www.javafx.org/. Cette suite contient un plugin pour Adobe Illustrator et Adobe Photoshop permettant de générer des fichiers .FXZ. Elle dispose également d’un convertisseur séparé capable de transformer un fichier .SVG en un fichier .FXZ ainsi qu’un visualisateur pour afficher un tel fichier. Elle fourni de plus la bibliothèque rajoutant le support du format FXD/FXZ dans JavaFX. Vous devrez rajouter cette bibliothèque à la liste des dépendances de votre projet pour être capable de manipuler le fichier .FXZ généré depuis votre application.

    De plus, le logiciel Inkscape est capable, nativement, d’exporter un fichier .SVG en un script .FX. Attention cependant, seule la version de développement supporte actuellement cette fonctionnalité et les scripts ainsi générés ne sont pour le moment pas compatibles avec la version finale de JavaFX.

    Que sont les fichiers FXD et FXZ ?
    Un fichier .FXZ (JavaFX Zipped Asset File) est une archive au format ZIP qui contient un fichier FXD (JavaFX Description File) qui lui contient du JavaFX Script. Cette archive peut également inclure des images bitmaps ou des fichiers de polices de charactères qui sont utilisées dans le design.

    Il existe également des fichiers .FXM (JavaFX MultiMedia File) contenant des séquences vidéo encodées avec le codec On2 et du son encodé en MP3.

    Puis-je utiliser des filtres dans la création de mon design ?
    De manière générale, dans la version actuelle, la plupart des filtres et effets avancés seront perdus durant la transformation ; il faut donc se restreindre à l'utilisation de formes simples et souvent vérifier que votre design garde une apparence correcte grace aux outils de prévisualisation fournis. Certains effets comme le Drop shadow (ombre portée) de Photoshop ou Illustrator (pas celui de Inkscape) peuvent cependant être conservés. Ce filtre, par exemple, sera traduit en un javafx.scene.effect.DropShadow sur chaque forme sur lequel il est activé. Il reste possible de rajouter des effets en éditant directement le FXD/FXZ après sa génération.

    On peut espérer que la Production Suite prenne plus d'effets en compte dans les mois à venir.

    Comment garder des références sur les différentes éléments (objets, groupes, calques, etc…) de mon design ?
    Dans votre éditeur, vous devez affecter un nom à chacune des entités que vous voulez manipuler par la suite. Si vous utilisez le convertisseur de la Production Suite, il est conseillé de préfixer les noms des entités par "jfx:".

    Attention certaines limitations peuvent intervenir suivant votre éditeur ; par exemple, Inkscape ne permet que de changer le label de calques en passant par la fenêtre Layers. Or, il se trouve que le convertisseur de la Production Suite utilise le champs ID de l’objet, le nom des calques sera donc perdu. Il reste cependant possible de changer l'ID du calque en passant par l'editeur XML intégré à Inkscape.
    De plus, lors de la conversion d’un fichier .SVG, le convertisseur de la JavaFX Production Suite 1.0 ignore les champs ID sur les objets <svg:text>, ces derniers perdront donc également leur identifiant.

    Si vous utilisez NetBeans, vous pourrez rajouter ces champs ultérieurement en éditant directement le fichier produit. Sinon, vous pouvez éditer le fichier FXD contenu dans le fichier FXZ pour rajouter les identificateurs manquants

    Comment générer un stub pour manipuler mon fichier FXD/FXZ ?
    Ouvrez directement votre fichier FXD/FXZ dans NetBeans. En haut de la fenêtre assurez-vous que le bouton Preview est sélectionné, ce qui affiche graphiquement votre design. Tout à droite de la barre d’outils de la fenêtre du fichier, cliquez sur Generate UI Stub (Ctrl + G) ; NetBeans vous proposera alors de générer une classe stub vous permettant de manipuler les entités contenues dans votre design.

    Si vous avez correctement nommé les entités de votre design, vous remarquerez que la classe ainsi générée contient une variable de type Node pour chaque entité déclarée dans votre design initial.

    Un gradient défini dans un éditeur externe s’affiche tout noir lorsque j’importe le fichier FXD/FXZ ?
    J’ai défini un gradient avec des couleurs s’arrêtant aux mêmes stops et il s’affiche tout noir ?
    JavaFX repose sur Java2D, hors il est impossible actuellement de définir un gradient dont les couleurs ont les mêmes valeurs de stop. Vous devrez donc modifier la définition de votre gradient pour être sur que les valeurs des stops soient strictement croissantes.

    Si vous avez défini ce gradient dans un éditeur externe (Illustrator, Photoshop, Inkscape, etc…), vous devez éditer ce gradient dans cet éditeur et réexporter votre projet au format FXD/FXZ. Si vous disposez de NetBeans vous pouvez directement modifier la définition du gradient dans le fichier FXD/FXZ.
    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
    Expert Confirmé Sénior

    Inscrit en
    mai 2003
    Messages
    3 283
    Détails du profil
    Informations forums :
    Inscription : mai 2003
    Messages : 3 283
    Points : 9 776
    Points
    9 776

    Par défaut

    Un grand merci. Je les ai déjà intégrée dans la FAQ qu'on vous prépare.

    Vincent Brabant

    Ne pas me contacter par MP ni par mail pour des questions techniques. Ma liste d'amis restera vide.

  4. #4
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Petite correction/precision, une fois le stub genere (d'apres mes tests et les exemples de Sun) :

    SVG => FXD => UI Stub

    - path (forme) : <svg:path>, <svg:rect>, etc... => SVGPath, Rectangle, etc... => Node
    - layer (calque) : <svg:g> racine dans Inkscape => Group racine => Node
    - group (groupe de formes, textes ou sous-groupes) : <svg:g> => Group => Node
    - text (texte) : <svg:text> => Text => Text
    - linear gradient (gradient lineaire) : <svg:linearGradient> => LinearGradient
    - radial gradient (gradient circulaire) : <svg:radialGradient> => RadialGradient


    Si les entites sont correctement nommees bien sur avant de passer au convertisseur (et compte tenu qu'il perd les ID des <svg:text> en chemin). Sinon pour voir les types concrets il suffit d'ouvrir le FXD.

    Faudrait que j'essaie de nommer les gradients pour voir s'il sont accessibles dans le stub...
    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
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Comment afficher une fenêtre ?

    Pour afficher une fenêtre, il suffit d’inclure un objet de type javafx.stage.Stage dans le script. Il est possible de lui donner un titre, des dimensions, sa position et divers autres attributs.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    import javafx.stage.Stage;
     
    Stage {
        title: "Une fenetre "
        width: 300
        height: 200
    }
    La fenêtre ainsi définie s’affichera immédiatement.

    Comment spécifier l’apparence d’une fenêtre ?
    La classe Stage dispose d’un champ style de type javafx.stage.StageStyle. StageStyle est une énumération qui liste tous les modes de décoration de fenêtre disponible.

    • StageStyle.DECORATED : la fenêtre dispose de ses décorations normales.
    • StageStyle.UNDECORATED : la fenêtre n’a plus de décorations et est complètement opaque.
    • StageStyle.TRANSPARENT : la fenêtre n’a plus de décorations et est complètement transparente (requiert Java 1.6.0 u10 ou plus).


    Ce champs doit être configuré à l’initialisation de la fenêtre et il n’est plus possible de le modifier après coup.

    Comment définir une fenêtre décorée et opaque ?
    C’est le comportement par défaut, vous pouvez cependant spécifier StageStyle.DECORATED si vous le désirez.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    import javafx.stage.Stage;
     
    Stage {
        title: "Une fenetre "
        width: 300
        height: 200
    }
    ou
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
     
    Stage {
        title: "Une fenetre decoree"
        width: 300
        height: 200
        style: StageStyle.DECORATED
    }
    Comment définir une fenêtre non-décorée et opaque ?
    Il faut spécifier StageStyle.UNDECORATED .

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
     
    Stage {
        title: "Une fenetre non-decoree"
        width: 300
        height: 200
        style: StageStyle.UNDECORATED
    }
    Comment définir une fenêtre non-décorée et transparente ?
    Il faut spécifier StageStyle.TRANSPARENT. Vous devez disposer de java 1.6.0 u10 ou plus pour que ceci fonctionne.


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
     
    Stage {
        title: "Une fenetre transparente"
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT
    }
    Alternativement, vous pouvez également utiliser StageStyle.UNDECORATED et faire varier l’opacité de la fenêtre à 0. Vous devez disposer de java 1.6.0 u10 ou plus pour que ceci fonctionne.

    Comment faire varier l’opacité de la fenêtre ?
    Vous devez utiliser le champs opacity de la classe Stage. La valeur du champ doit être comprise entre 0 (complètement transparent) et 1 (complètement opaque). Vous devez disposer de java 1.6.0 u10 ou plus pour que ceci fonctionne.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    import javafx.stage.Stage;
     
    Stage {
        title: "Une fenetre semi-transparente"
        width: 300
        height: 200
        opacity: 0.5
    }
    Note de moi : cela ne fonctionne toujours pas chez moi avec la 1.6.0 u11, je suis donc dans l’impossibilité de vérifier correctement cela.

    Comment utiliser l’API SceneGraph ?
    Vous devez inclure un objet de type javafx.scene.Scene dans votre Stage. Vous placerez ensuite des objets de type javafx.scene.Node (ces objet peuvent contenir du texte, des formes vectorielles, des images, des composants Swing, un design fait dans un logiciel externe…) dans cette scène pour créer votre interface graphique.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    import javafx.scene.Scene;
    import javafx.stage.Stage;
     
     
    Stage {
        title: "Une fenetre avec une scene "
        width: 300
        height: 200
        scene: Scene { }
    }
    Après l’ajout d’une scène, ma fenêtre n’est plus transparente ?
    La couleur de fond d’une scène est blanche (javax.scene.paint.Color.WHITE) par defaut. Vous devez donc la remplacer par la couleur transparente (javax.scene.paint.Color.TRANSPARENT) :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    import javafx.paint.Color;
     
    Stage {
        title: "Une fenetre avec une scene transparente "
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT
        scene: Scene { 
          fill: Color.TRANSPARENT
       }
    }
    Que sont les effets ?
    Les effets sont des classes proposant des effets graphiques à appliquer aux formes ou à la scène que vous désirez afficher. Ils sont définis dans le package javafx.scene.effect et ses sous-packages. Ce dernier contient les effets de base qui permettent de faire, entre autre des ombres portées ou du flou ou encore l’illumination d’un objet ou de la scène permettant ainsi de rendre plus réaliste cette dernière en faisant varier son éclairage.

    Ces effets reposent la plupart du temps sur la création d’images bitmap intermédiaires. Ils peuvent être gourmand tant en ressource CPU qu’en mémoire.

    Comment mettre en place un effet ?
    Il est possible de mettre un effet sur chaque Node de la scène en spécifiant son champ effect.

    Note : dans les exemples suivants nous partirons de ce code qui affiche un rectangle aux coins arrondis dans une fenêtre non-décorée dont le fond est transparent. Le rectangle possitionné en (50, 50) et de taille 200x100 est colorié avec un gradient linaire qui va du rouge au rouge foncé. Ce gradient colle aux extrémités du rectangle (utile si on redimensionne ce dernier).
    Code :
    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
     
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.Scene;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
    Stage {
        title: "Test d'effet"
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT;
        scene: Scene {
            fill: Color.TRANSPARENT
            content: Rectangle {
                x: 50, y: 50
                width: 200, height: 100
                arcWidth: 20, arcHeight: 20
                fill: LinearGradient {
                    startX: 0, startY: 0
                    endX: 0, endY: 1
                    proportional: true
                    stops: [
                        Stop {
                            offset: 0.0
                            color: Color.RED},
                        Stop {
                            offset: 1.0
                            color: Color.DARKRED}
                    ] // stops
     
                }
            }
        }
    }
    Comment faire une ombre portée ?
    Pour rajouter une ombre portée à notre rectangle, il suffit lui donner un effet javafx.scene.effect.DropShadow. Par exemple :

    Code :
    1
    2
    3
    4
    5
    6
     
              effect: DropShadow {
                    offsetX:10, offsetY: 10
                    radius: 50
                    spread: 0
                }
    Nous avons ici défini une ombre décalée de (+10, +10) par rapport à notre rectangle d’origine, sur laquelle nous allons appliquer un flou gaussien de 50. La notion de spread est un peu plus complexe, i l s‘agit de la position relative à partir de la quelle l’ombre devient floue. Cette valeur est comprise entre 0 (l’ombre est complètement floue) et 1 (l’ombre n’est pas du tout floue).

    Vous remarquerez qu’il n’est pas possible de faire varier l’opacité de l’ombre. Pour cela il faudra faire varier la transparence de la couleur utilisée pour cette ombre ; cette couleur peut-être spécifiée via le champ color (la valeur par défaut est Color.BLACK).

    Comme la forme de l’ombre va déborder largement de celle du rectangle, vous devez prévoir une taille de fenêtre suffisante sinon l’ombre sera coupée à l’endroit où la fenêtre se termine (même si cette dernière est non-décorée).

    Ce qui nous donne le code suivant :
    Code :
    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
     
    import javafx.scene.effect.DropShadow;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.Scene;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
    Stage {
        title: "Test d’ombre portee "
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT;
        scene: Scene {
            fill: Color.TRANSPARENT
            content: Rectangle {
                x: 50, y: 50
                width: 200, height: 100
                arcWidth: 20, arcHeight: 20
                fill: LinearGradient {
                    startX: 0, startY: 0
                    endX: 0, endY: 1
                    proportional: true
                    stops: [
                        Stop {
                            offset: 0.0
                            color: Color.RED},
                        Stop {
                            offset: 1.0
                            color: Color.DARKRED}
                    ] // stops
     
                }
                effect: DropShadow {
                    offsetX:10, offsetY: 10
                    radius: 50
                    spread: 0
                }
            }
        }
    }
    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
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Comment faire un flou gaussien ?
    Pour faire que notre rectangle apparaisse flouté, il suffit lui donner un effet javafx.scene.effect.GaussianBlur. Par exemple :

    Code :
    1
    2
    3
    4
     
              effect: GaussianBlur {
                    radius: 20
                }
    Ce qui nous donne le code suivant :
    Code :
    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
     
    import javafx.scene.effect.GaussianBlur;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.Scene;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
    Stage {
        title: "Test de flou gaussien "
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT;
        scene: Scene {
            fill: Color.TRANSPARENT
            content: Rectangle {
                x: 50, y: 50
                width: 200, height: 100
                arcWidth: 20, arcHeight: 20
                fill: LinearGradient {
                    startX: 0, startY: 0
                    endX: 0, endY: 1
                    proportional: true
                    stops: [
                        Stop {
                            offset: 0.0
                            color: Color.RED},
                        Stop {
                            offset: 1.0
                            color: Color.DARKRED}
                    ] // stops
     
                }
                effect: GaussianBlur {
                    radius: 20
                }
            }
        }
    }
    Comment faire varier les couleurs ?
    Pour faire varier les couleurs de notre rectangle, il suffit lui donner un effet javafx.scene.effect.ColorAdjust. Cette classe permet de faire varier les couleurs des pixels du Node source. Par exemple :

    Code :
    1
    2
    3
    4
    5
     
              effect: ColorAdjust {
                    hue: 0.5
                    brightness : 0.5
                }
    Ici nous faisons varier la composante hue (teinte) de la couleur, ce qui transformera notre rectangle rouge en un rectangle vert. Nous l’avons de plus éclairci en modifiant sa brightness (luminescence).

    Ce qui nous donne le code suivant :
    Code :
    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
     
    import javafx.scene.effect.ColorAdjust;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.Scene;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
    Stage {
        title: "Test de variation des couleurs"
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT;
        scene: Scene {
            fill: Color.TRANSPARENT
            content: Rectangle {
                x: 50, y: 50
                width: 200, height: 100
                arcWidth: 20, arcHeight: 20
                fill: LinearGradient {
                    startX: 0, startY: 0
                    endX: 0, endY: 1
                    proportional: true
                    stops: [
                        Stop {
                            offset: 0.0
                            color: Color.RED},
                        Stop {
                            offset: 1.0
                            color: Color.DARKRED}
                    ] // stops
     
                }
              effect: ColorAdjust {
                    hue: 0.5
                    brightness : 0.5
                }
            }
        }
    }
    Par contre vous pouvez remarquer un petit problème dans les coins (normalement transparents) de notre rectangle : ceux-ci sont devenus blancs semi-transparents. Apparemment il s’agit là d’un bug de jeunesse de JavaFX, si on enlève le changement de luminosité, les coins restent cependant transparents quand le rectangle devient vert.
    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
    Expert Confirmé Sénior

    Inscrit en
    mai 2003
    Messages
    3 283
    Détails du profil
    Informations forums :
    Inscription : mai 2003
    Messages : 3 283
    Points : 9 776
    Points
    9 776

    Par défaut

    Citation Envoyé par bouye Voir le message
    Petite correction/precision, une fois le stub genere (d'apres mes tests et les exemples de Sun) :

    SVG => FXD => UI Stub

    - path (forme) : <svg:path>, <svg:rect>, etc... => SVGPath, Rectangle, etc... => Node
    - layer (calque) : <svg:g> racine dans Inkscape => Group racine => Node
    - group (groupe de formes, textes ou sous-groupes) : <svg:g> => Group => Node
    - text (texte) : <svg:text> => Text => Text
    - linear gradient (gradient lineaire) : <svg:linearGradient> => LinearGradient
    - radial gradient (gradient circulaire) : <svg:radialGradient> => RadialGradient


    Si les entites sont correctement nommees bien sur avant de passer au convertisseur (et compte tenu qu'il perd les ID des <svg:text> en chemin). Sinon pour voir les types concrets il suffit d'ouvrir le FXD.

    Faudrait que j'essaie de nommer les gradients pour voir s'il sont accessibles dans le stub...
    Tu vois cela dans quelle Q/R en fait
    Vincent Brabant

    Ne pas me contacter par MP ni par mail pour des questions techniques. Ma liste d'amis restera vide.

  8. #8
    Rédacteur
    Avatar de eclesia
    Inscrit en
    décembre 2006
    Messages
    1 973
    Détails du profil
    Informations forums :
    Inscription : décembre 2006
    Messages : 1 973
    Points : 2 484
    Points
    2 484

    Par défaut

    Dans une partie dédiée aux fonctions :

    Comment définir le point d'entrée de mon application ?

    Vous pouvez définir l'equivalant Java de la fonction :
    Code :
    public static void main(String[] args){...}
    JavaFX :
    Code :
    public function run(args: String[]){...}
    A la difference de Java, cette fonction doit etre en dehors de la classe.

    Par défaut JavaFX génére implicitement cette fonction, c'est pourquoi il n'est pas nécessaire de l'ecrire si vous n'en avez pas l'utilité.

  9. #9
    Rédacteur
    Avatar de eclesia
    Inscrit en
    décembre 2006
    Messages
    1 973
    Détails du profil
    Informations forums :
    Inscription : décembre 2006
    Messages : 1 973
    Points : 2 484
    Points
    2 484

    Par défaut

    Dans une partie dédiée aux fonctions :

    Ou se trouve le constructeur de ma classe ?

    Les classes JavaFX n'offrent pas la possibilité d'avoir des constructeurs avec différents paramètres.

    En revanche il est possible d'utiliser le mot clé : public-init afin de permetre la configuration des variables à la création.

    Deux fonctions sont aussi disponibles si vous souhaitez faire diverses opérations :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class MaClass{
     
        init {...}
     
        postinit {...}
     
    }

  10. #10
    Rédacteur
    Avatar de eclesia
    Inscrit en
    décembre 2006
    Messages
    1 973
    Détails du profil
    Informations forums :
    Inscription : décembre 2006
    Messages : 1 973
    Points : 2 484
    Points
    2 484

    Par défaut

    Comment afficher mes composants SWING dans JavaFX ?

    Swing et JavaFX utilise la meme API de rendue : Java2D
    Il est donc relativement simple d'intégrer un composant SWING dans une interface javaFX.

    Première solution : utiliser l'outil fourni
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    import javafx.ext.swing.SwingComponent;
    ...
     
    var swingfxComponent = SwingComponent.wrap( new MonComposantSwing() );
     
    Stage {
        scene: Scene{
        content: Content[
            swingfxComponent,
            ...
            ]
        }
    }
    L'inconvénient de cette méthode est qu'il n'est pas possible de faire de binding sur les différentes variables de notre noeud car cela doit etre fait a la creation.

    Seconde solution : par héritage
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    import javafx.ext.swing.SwingComponent;
    ...
     
    public class MonFXComponent extends SwingComponent{
     
        /*on garde ici une reference public pour pouvoir acceder a notre composant*/
        public-read var monComp : MonComposantSwing;
     
        public override function createJComponent(): J2DMapVolatile{
            monComp = new MonComposantSwing();
            return monComp;
        }
    }
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    var swingfxComponent:MonFXComponent = MonFXComponent{
            translateY: bind ...
            translateX: bind ...
            effect: ...
        }
     
    Stage {
        scene: Scene{
        content: Content[
            swingfxComponent,
            ...
            ]
        }
    }

    Si vous n'avez a afficher qu'un composant plus ou moins statique (JLabel, Image ...) il est préférable d'utiliser la première solution.
    Si vous avez besoin de modifier le composant au cours de l'application alors il vaut mieux utiliser la seconde.

  11. #11
    Rédacteur
    Avatar de eclesia
    Inscrit en
    décembre 2006
    Messages
    1 973
    Détails du profil
    Informations forums :
    Inscription : décembre 2006
    Messages : 1 973
    Points : 2 484
    Points
    2 484

    Par défaut

    A ajouter dans les sources d'informations :

    le lien vers la javafxdoc :
    http://java.sun.com/javafx/1/docs/api/index.html

  12. #12
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Citation Envoyé par vbrabant Voir le message
    Tu vois cela dans quelle Q/R en fait
    Dans ce qui a rapport au convertisseur SVG => FXD

    Au niveau intitulé... euh...

    Que deviennent mes entités SVG une fois converties en FXD ? ou quelques chose du genre.

    Mais il faudra remettre ca en forme pour simplifier la présentation et la rendre plus explicite.
    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

  13. #13
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Quelques tests supplementaires concernant les classes abstraites (avec correction de qq chose que j'ai dis dans le forum prive) :

    Comment déclarer une classe abstraite ?
    Pour déclarer une classe comme étant abstraite, il suffit de précéder son nom du mot clé abstract.

    Code :
    1
    2
    3
    4
     
    abstract class Toto {
      public var  titi:Number  = 0;
    }
    Comment déclarer une fonction abstraite ?
    Pour déclarer une fonction comme étant abstraite, il suffit de précéder son nom du mot clé abstract et de lui donner un corps vide.
    Une telle fonction ne peut être définie que dans une classe abstraite. Si votre classe n’est pas abstraite vous aurez un message d’erreur du compilateur ou de votre IDE.

    Code :
    1
    2
    3
    4
    5
     
    abstract class Toto {
      public var  titi:Number  = 0;
      public abstract function faireQuelqueChose():Void;
    }
    Comment utiliser une classe abstraite ?
    Une classe abstraite peut être étendue par une autre classe à l’aide du mot-clé extends :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class TotoConcret extends Toto {
      override public function faireQuelqueChose():Void {
        println(titi ) ;
      }
    }
     
    var toto = TotoConcret {
    }
    Mais il est également possible de l’implémenter dans une classe anonyme :
    Code :
    1
    2
    3
    4
    5
    6
     
    Var toto = Toto {
      override public function faireQuelqueChose():Void {
        println(titi) ;
      }
    }
    L’usage du mot-clé override est obligatoire dans les deux cas.

    Comment déclarer une enum ?
    Il n’est pour le moment pas possible de déclarer une enum en JavaFX même si certaines classes de l’API JavaFX sont elles-mêmes des enums (par exemple la classe javafx.stage.StageStyle). En fait ces enums sont tout simplement déclarées en Java, il vous est en effet possible de mélanger du code source Java et JavaFX dans votre projet JavaFX (en tout cas NetBeans le permet).
    <lien sur la FAQ Java indiquant comment créer des enums>
    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

  14. #14
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Pour l'exemple suivant j'ignore le nom officiel de ces mécanismes. Je les appelle donc temporairement [barré]un pointeur[/barré] une référence sur une fonction et un "callback".

    Comment définir une référence de fonction ?
    Pour JavaFX, une signature de fonction est un type comme un autre. Il est donc possible de définir une variable comme étant une référence sur une fonction et appeler cette fonction quand on appelle cette variable. Pour ce faire, il faut déclarer la variable suivie de :, puis du mot-clé function puis de la liste des arguments de la fonction entre parenthèse puis de : et de son type de retour.

    Par exemple :
    Code :
    1
    2
     
    var bonjour: function():Void;
    Ici bonjour est une référence vers une fonction qui ne prend pas d’argument et ne retourne rien. Par défaut, bonjour est initialisé à null. Si nous appellons :
    Rien ne se passe.
    De plus si nous imprimons la valeur de bonjour en faisant :
    Code :
    1
    2
     
    println(bonjour) ;
    Nous obtenons :

    Nous pouvons cependant lui affecter une valeur, définissons par exemple la fonction suivante :
    Code :
    1
    2
    3
    4
     
    function direBonjour() {
        println("Salut le monde !");
    }
    Si nous faisons :
    Code :
    1
    2
    3
    4
    5
    6
    7
     
    var bonjour: function():Void;
    function direBonjour() {
        println("Salut le monde !");
    }
    bonjour = direBonjour;
    bonjour();
    Notre programme va afficher le message Salut le monde !.
    Si nous imprimons la valeur de bonjour, nous obtiendrons quelques chose de similaire à :

    Code :
    1
    2
     
    monScript$1@1506dc4
    Qui est la valeur de la référence sur la fonction que nous utilisons.
    Nous pouvons bien sur affecter d’autres valeurs à notre variable en cours d’exécution, ainsi le code suivant :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    var bonjour: function():Void;
    println("=============================");
    println(bonjour);
    bonjour();
    println("=============================");
    function test1():Void {
        println("Hello world!");
    }
    bonjour = test1;
    println(bonjour);
    bonjour();
    println("=============================");
    function test2():Void {
        println("Salut le monde !");
    }
    bonjour = test2;
    println(bonjour);
    bonjour();
    Produira quelques chose de similaire à :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    =============================
    null
    =============================
    monScript$1@1506dc4
    Hello world!
    =============================
    monScript$2@a761fe
    Salut le monde !
    Car :
    1. La variable est initialisée à null rien ne s’affiche.
    2. La variable prend la référence de la fonction test1() et affiche Hello world!.
    3. La variable prend la référence de la fonction test2() et affiche Salut le monde !.


    Si nous essayons d’affecter des fonctions dont la signature ne correspond pas à la définition de notre variable des erreurs seront générées par le compilateur ou l’IDE.
    Ainsi le code suivant ne compilera pas :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function test3(x:Number):Void {
        println("{x}");
    }
    bonjour = test3;
    println(bonjour);
    bonjour ();
    function test4():Number {
        return 0;
    }
    bonjour = test4;
    println(bonjour);
    bonjour ();
    En effet aucune des deux fonctions ne correspond à la signature utilisée pour la définition de bonjour.

    Il est bien sur possible de définir des signatures de référence sur des fonctions prenant en paramètres plusieurs arguments ou ayant des types de retour. Ainsi le code suivant est tout à fait valide :
    Code :
    1
    2
    3
    4
    5
    6
    7
     
    var add:function(x:Number, y:Number):Number;
    function addNumber(x:Number, y:Number):Number {
        return x+y;
    }
    add=addNumber;
    println(add(3, 4));
    Une fois executé ce code affichera la valeur 7.0.

    On remarquera également qu’il est impossible d’appeler la variable add sans argument ou avec le mauvais nombre d’argument entre les parenthèses car cela ne correspond pas à la signature utilisée. Ainsi le code suivant ne compilera pas :
    Code :
    1
    2
    3
    4
     
    println(add());
    println(add(1));
    println(add(1, 2, 3));
    Avant d’utiliser des références de fonction, vous devez cependant pendre garde à ce que vos références soient correctement initialisées. Ainsi :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var add:function(x:Number, y:Number):Number;
    println(add(3, 4));
    println(add);
    println("=============================");
    function addNumber(x:Number, y:Number):Number {
        return x+y;
    }
    add=addNumber;
    println(add(3, 4));
    println(add);
    Produira un résultat similaire à :

    Code :
    1
    2
    3
    4
    5
    6
     
    0.0
    null
    =============================
    7.0
    monScript$1@a761fe
    En effet :
    1. La variable add est non-initialisée et donc à null. La valeur retournée est 0.0 qui est la valeur par défaut des Number.
    2. La variable add est initialisée avec notre fonction et retourne la valeur correcte.


    Il faudra donc manier ce concept avec précautions.

    Comment faire un callback ?
    Il est possible de faire un callback en créant une variable qui est une référence de fonction à l’intérieur d’une classe. Par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class Toto {
        public var onXXXChange:function():Void;
     
        public function faireQuelqueChose():Void {
            onXXXChange();
        }
    }
    Dans ce cas la variable onXXXChange, elle est définie comme étant une référence sur une fonction qui ne prend pas d’argument et qui ne retourne rien. Nous pouvons donc appeler cette variable comme s’il s’agissait d’une fonction depuis le code de la classe et il est également possible d’accéder directement à cette variable depuis l’extérieur de la classe.
    Par défaut la variable est initialisée à null et le code ne fait strictement rien.

    Note : le nom de la variable importe peu et vous pouvez la nommer comme bon vous semble.

    Si nous écrivons :
    Code :
    1
    2
    3
    4
     
    var toto1 = Toto{
    }
    toto1.faireQuelqueChose();
    À l’exécution, il ne se passe rien.

    Lorsque nous implémentons notre classe, il est possible de redéfinir la variable onXXXChange comme n’importe quelle autre variable publique qui ne soit pas marquée public-read.

    Par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
     
    var toto2 = Toto {
        onXXXChange: function():Void {
            println("onXXXChange");
        }
    }
    toto2.faireQuelqueChose();
    À l’execution la chaine de texte onXXXChange s’affichera.

    Vous pouvez remarquer que la gestion des évènements claviers et souris dans l’API SceneGraph fonctionne exactement de la même maniere, vous serez donc ammener à surcharger les valeurs par défaut des variables onMouseClicked ou onKeyPressed (par exemple) pour gérer les événements dans la classe javafx.stage.Node et ses classes filles.

    Vous pouvez sans problème définir des variables avec des signatures de fonction qui prennent plusieurs arguments ou qui ont même un type de retour. Dans tous les cas, vous devrez faire attention à ce que vos variables soient correctement définies :
    Code :
    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
     
    public class Toto {
        public var onXXXChange:function():Void;
     
        public var onYYYChange:function(x:Number, y:Number):Number;
     
        public function faireQuelqueChose1():Void {
            onXXXChange();
        }
     
        public function faireQuelqueChose2(x:Number, y:Number):Number {
           return onYYYChange(x, y);
        }
    }
     
    var toto1 = Toto{
    }
    var toto2 = Toto {
        onXXXChange: function():Void {
            println("onXXXChange");
        }
        onYYYChange: function(x:Number, y:Number):Number {
            println("{x}, {y}");
            return x+y;
        }
    }
    println("=======================");
    toto1.faireQuelqueChose1();
    println(toto1.onYYYChange);
    println(toto1.onYYYChange(1, 2));
    println(toto1.faireQuelqueChose2(1, 2));
    println("=======================");
    toto2.faireQuelqueChose1();
    println(toto2.onYYYChange);
    println(toto2.onYYYChange(1, 2));
    println(toto2.faireQuelqueChose2(1, 2));
    Le résultat de l’exécution d’un tel code sera :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    =======================
    null
    0.0
    0.0
    =======================
    onXXXChange
    monScript$2@1be0f0a
    1.0, 2.0
    3.0
    1.0, 2.0
    3.0
    1. Dans le cas de toto1 :
      1. L’appel à la methode faireQuelqueChose1() n’imprime rien car onXXXChange n’est pas défini.
      2. L'impression directe de onYYYChange affiche null car onYYYChange n’est pas défini.
      3. L’acces direct direct à onYYYChange retourne retourne 0.0 qui est la valeur des Number (le type de retour dans la signature de la fonction) par défaut.
      4. L’appel à la méthode faireQuelqueChose2() retourne 0.0 qui est la valeur des Number par défaut.
    2. Dans le cas de toto2 :
      1. L’appel à la méthode faireQuelqueChose1() imprime bien onXXXChange puisque la fonction que nous avons définie est appelée.
      2. L'impression directe de onYYYChange affiche la référence de la fonction que nous avons defini.
      3. L’accès direct à onYYYChange imprime bien les valeurs de x et y et retourne le résultat correct de la fonction que nous avons défini.
      4. L’appel à la méthode faireQuelqueChose2() imprime bien les valeurs de x et y et retourne le résultat correct de la fonction que nous avons défini.

    Une fois de plus, il faudra donc manier ce concept avec précautions.
    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

  15. #15
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Comment faire une animation ?
    Les animations sont construites à partir de la classe javafx.animation.Timeline et des autres classes présentes dans le package javafx.animation. Une animation consiste en une séquence d’étapes ou animations clés appelées « key Frames » placées dans une ligne temporelle. Ces étapes, permettent d’indiquer les changements dans l’état des variables qui servent à animer notre objet graphique. Une étape clé est modélisée par la classe javafx.animation.KeyFrame.

    L’exemple suivant affiche un rectangle aux bords arrondis et rempli d’un dégradé rouge dans une fenêtre non-décorée :
    Code :
    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
     
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.Scene;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
    var rect = Rectangle {
        x: 50,
        y: 50
        width: 200,
        height: 100
        arcWidth: 20,
        arcHeight: 20
        fill: LinearGradient {
            startX: 0,
            startY: 0
            endX: 0,
            endY: 1
            proportional: true
            stops: [
                Stop {
                    offset: 0.0
                color: Color.RED},
                Stop {
                    offset: 1.0
                color: Color.DARKRED}
            ] // stops
     
        }
            };
    Stage {
        title: "Test d'animation"
        width: 300
        height: 200
        style: StageStyle.TRANSPARENT;
        scene: Scene {
            fill: Color.TRANSPARENT
            content: rect;
        }
    }
    Pour animer le rectangle en faisant varier sa largeur, définie dans son champ width, nous pouvons déclarer une animation de la manière suivante :

    Code :
    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
     
    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
     
    [...]
     
    var anim = Timeline {
        repeatCount: Timeline.INDEFINITE;
        autoReverse: true;
        keyFrames: [
            KeyFrame {
                time: 0s;
                action: function():Void {
                    rect.width = 200;
                }
            }
            KeyFrame {
                time: 1s;
                action: function():Void {
                    rect.width = 50;
                }
            }
        ]
    }
    anim.playFromStart();
    Ce code définie une animation qui dure 1 seconde : il y a une étape clé à 0 seconde et une autre à 1 seconde. Grace au callback que nous avons défini dans la variable action de chaque étape, nous pouvons affecter une nouvelle largeur à notre rectangle. Notre animation se répète indéfiniment car nous avons spécifié la constante Timeline.INDEFINITE, nous aurions pu également spécifier un nombre supérieur ou égal à 1.

    De plus, le champ autoReverse indique que l’animation s'inverse lorsqu’elle arrive à la fin. Ainsi l’animation ira de l’étape 0s à l’étape 1s (1 seconde d’attente entre les deux étapes) puis de l’étape 1s à l’étape 0s (à nouveau 1 seconde d’attente entre les deux étapes). Si ce champ est omis, l’animation passera directement de l’étape 1s à l’étape 0s et nous ne verrons jamais varier la largeur du rectangle.

    L’appel à anim.playFromStart(); permet de démarrer une animation depuis le début de la ligne temporelle.

    Comment arrêter une animation ?
    Il suffit d’appeler sa méthode stop().

    Comment relancer une animation ?
    Il suffit d’appeler sa méthode play(). L’animation reprendra à partir du point où elle s’est précédemment arrêtée. Si elle n’a jamais été lancée précédemment, elle démarrera au temps 0 de la ligne temporelle.

    Comment relancer une animation depuis le début ?
    Il suffit d’appeler sa méthode playFromStart(). Cette méthode relancera l’animation depuis le début de la ligne temporelle.

    Comment changer la vitesse d’une animation
    Il est possible de modifier la vitesse d’une animation en modifiant son champ rate. Celui-ci est à 1 par défaut.

    Pour doubler la vitesse d’une animation il suffit de le mettre à 2.
    Pour ralentir une animation de moitié, il suffit de le mettre à 0.5.

    Comment inverser une animation ?
    Il suffit de lui donner une valeur négative pour son champ rate. L’animation ira alors à rebours depuis son emplacement actuel dans la ligne temporelle.

    Comment spécifier où se trouve l’animation dans la ligne temporelle ?
    Il faut modifier son champ time en lui donnant une Duration.

    Comment spécifier le nombre de répétitions d’une animation ?
    Il faut modifier son champ repeatCount. Sa valeur par défaut est 1.0, l’animation s’exécutera donc une seule et unique fois. Pour répéter l’animation indéfiniment, il faut utiliser la valeur javafx.animation.Timeline.INDEFINITE.

    Comment inverser l’animation automatiquement quand elle se répète ?
    Il faut mettre son champ autoReverse à la valeur true. Si l’animation se répète plus d’une fois, son rate sera inversé à chaque fois qu’elle arrive à une extrémité de sa ligne temporelle.
    La valeur par défaut de ce champ est false.

    Comment faire une animation interpolée ?
    Notre animation se contente de modifier la largeur du rectangle à l’étape 0s puis à l’étape 1s ce qui n’est guère joli à l’écran. Il est possible de spécifier que les valeurs qui sont animées sont en fait interpolées à chaque pas de temps. Ainsi le code suivant :
    Code :
    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
     
    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
     
    [...]
     
    var anim = Timeline {
        repeatCount: Timeline.INDEFINITE;
        autoReverse: true;
        keyFrames: [
            KeyFrame {
                time: 0s;
                values: [
                    rect.width => 200
                ]
            }
            KeyFrame {
                time: 1s;
                values: [
                    rect.width => 50
                ]
            }
        ]
     }
    anim. playFromStart() ;
    Produira une animation fluide de la largeur du rectangle.

    La notation variable => valeur est un raccourci qui évite de devoir créer manuellement des objets de type javax.animation.KeyValue et javax.animation.KeyValueTarget. Il est de plus possible de simplifier la création des étapes clés en utilisant la notation suivante ce qui évitera de devoir créer des KeyFrame manuellement :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var anim = Timeline {
        repeatCount: Timeline.INDEFINITE;
        autoReverse: true;
        keyFrames: [
          at(0s) {
            rect.width => 200;
          }
          at(1s) {
            rect.width => 50;
          }
        ]
     }
    Enfin JavaFX peut estimer pour vous les conditions initiales des variables qui sont animées, on peut ainsi omettre l’étape clé à 0s :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var anim = Timeline {
        repeatCount: Timeline.INDEFINITE;
        autoReverse: true;
        keyFrames: [
            KeyFrame {
                time: 1s;
                values: [
                    rect.width => 50
                ]
            }
        ]
     }
    Ou encore :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var anim = Timeline {
        repeatCount: Timeline.INDEFINITE;
        autoReverse: true;
        keyFrames: [
          at(1s) {
            rect.width => 50;
          }
        ]
     }
    Ainsi à 0 secondes, rect.width reviendra à sa valeur initiale qui était de 200 lorsque nous avons défini notre variable rect.

    Comment spécifier le type d’interpolation à utiliser ?
    Il est possible de spécifier l’interpolation en utilisation le mot-clé tween suivit d’une instance d’un javafx.animation.Interpolator. L’interpolation par défaut est linéaire.

    Ainsi la définition suivante :

    Est équivalente à :

    Code :
    1
    2
    3
    4
    5
    6
     
    import javafx.animation.Interpolator;
     
    [...]
     
            rect.width => 50 tween Interpolator.LINEAR;
    Si nous spécifions au contraire :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var anim = Timeline {
        repeatCount: Timeline.INDEFINITE;
        autoReverse: true;
        keyFrames: [
          at(1s) {
            rect.width => 50 tween Interpolator.EASEOUT;
          }
        ]
     }
    L’animation de notre rectangle donnera l’impression d’être amorti quand sa largeur approchera de sa plus petite valeur (à l’étape clé 1s) donnant l’impression d’un mouvement plus naturel. Au contraire l’utilisation d’Interpolator.EASEIN accélérera le mouvement à l’approche de l’étape clé 1s.

    Utiliser des interpolations dans la ligne temporelle permet de simuler des mouvements qui paraissent plus naturels et plus agréables à l’œil, par exemple si nous désirons animer un piston hydraulique.

    Comment définir son propre type d’interpolation ?
    Vous pouvez soit directement étendre la classe javafx.animation.Interpolator soit sa classe fille javafx.animation.SimpleInterpolator.
    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

  16. #16
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Comment imprimer sur la sortie standard ?
    Vous pouvez utiliser les fonctions globales print() ou println(). Par exemple :
    Code :
    1
    2
     
    println("Bonjour le monde !") ;
    Ce code affichera " Bonjour le monde !" suivit d’un saut de ligne.

    Vous pouvez également importer la classe java.lang.System et utiliser System.out.print(), System.out.println() ou System.out.printf() (comme en Java).

    Comment concaténer deux chaines de caractères ?
    Vous pouvez placer deux chaines de caractère cote à cote avec ou sans espace entre pour les concaténer :
    Code :
    1
    2
    3
    4
    5
     
    var c1 = "a""b";
    println(c1);
    var c2 = "a" "b";
    println(c2);
    Ici c1 et c2 contiennent chacun "ab".

    Si jamais vos chaines de caractère sont stockées dans des variables vous pouvez les concaténer avec des string expression :
    Code :
    1
    2
    3
    4
    5
     
    var a = "a";
    var b = "b";
    var c3 = "{a}{b}";
    println(c3);
    c3 contient également "ab".
    <lien vers la Q/R sur les string expression>

    Que sont les séquences ?
    En JavaFX les séquences sont des jeux de données indexées. Le premier élément d’une séquence est à l’indice 0, le second à l’indice 1, etc. jusqu’au dernier qui se trouve à l’indice <taille de la séquence -1>.

    On peut les voir comme des équivalents des tableaux en Java ou dans d’autres langages. Attention cependant les séquences JavaFX ne sont pas des tableaux Java !

    Le didacticiel JavaFX vous montrera les usages avancés des séquences (parcours avec critère, insertion, suppression d’élément, extraction d’une sous-séquence, etc.).
    <Lien vers le didacticiel>

    Comment déclarer une séquence ?
    Une séquence peut être déclarée en listant tous ses éléments entre crochets, par exemple :
    Code :
    1
    2
     
    var joursDeLaSemaine = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi",  "Dimanche"] ;
    Si les éléments dans votre séquence ne sont pas des chaines de caractères, vous pouvez omettre la virgule comme séparateur. Par exemple :
    Code :
    1
    2
    3
    4
    5
     
    var nombres = [1 2];
    var booleens = [true false];
    var groupes = [Group{} Group{}];
    var chaines = ["a" "b"];
    Ici nombres, booleens et groupes sont toutes des séquences de taille 2. Tandis que chaines est une séquence de taille 1 car "a" et "b" ont été concaténés.

    Comment accéder aux éléments d’une séquence ?
    Il est possible d’accéder aux éléments d’une séquence en utilisant la notation habituelle des tableaux : le nom de la séquence suivit de l’indice de la valeur entre crochets.

    Par exemple :
    Code :
    1
    2
    3
     
    var lundi = joursDeLaSemaine[0] ;
    var mardi = joursDeLaSemaine[1] ;
    Ici la variable lundi contient désormais la valeur "Lundi" tandis que la variable mardi contient la valeur "Mardi".

    Comment connaître la taille d’une séquence ?
    Il faut utiliser l’opérateur sizeof. Par exemple :
    Code :
    1
    2
    3
     
    var nombres = [1 2];
    println(sizeof nombres);
    Ce code imprimera 2, la taille de la séquence nombres.

    Que sont les string expressions ?
    Les string expressions sont des expressions placées dans une chaine de caractère que JavaFX peut évaluer au moment de l’exécution. Elles peuvent référencer des variables, ou même d’autres expressions. Par exemple :
    Code :
    1
    2
    3
     
    var toto = "test";
    println("{toto}");
    Ceci imprimera la chaine test.

    Tandis que le code suivant :
    Code :
    1
    2
     
    println("{if(true) { true } else { false }}");
    Imprimera true.

    Comment déclarer une string expression ?
    Pour déclarer une string expression il suffit d'écrire une expression entre accolades dans une chaine de caractère. Par exemple :
    Code :
    1
    2
    3
    4
    5
     
    "{toto}"
    "{Math.max(1, 2)}"
    "{if(true) { true } else { false }}"
    "{for (jour in joursDeLaSemaine) { "{jour}, " } }"
    Sont toutes des string expressions valides.

    Le dernier exemple qui indique comment imprimer une séquence définissant les jours de la semaine montre d’ailleurs une string expression à l’intérieur d’une autre string expression.

    Comment connaitre le répertoire ou package courant ?
    Vous devez utiliser la constante globale __DIR__.

    Ceci imprimera le répertoire courant ou le package à l’intérieur du fichier JAR dans lequel se trouve le script en train d’être exécuté.

    Vous pouvez également placer cette constante dans une string expression ce qui peut être utile pour construire des chemins ou des URL vers des ressources (images, sons, fichiers de propriétés, etc.) qui sont utilisées par vos classes.

    Code :
    1
    2
     
    "{__DIR__}son.wav";
    Note : le chemin retourné par __DIR_ se termine par un séparateur, il n'est donc pas nécessaire de le rajouter quand on construit un tel chemin. Ceci peut être une source d'erreur.
    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

  17. #17
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Qu’est ce qui est considéré comme étant à l’intérieur de mon nœud ?
    Généralement dans le cas de nœuds qui sont des formes géométriques, des groupements de nœuds ou des composants Swing, les parties du nœud qui sont complètement transparentes (avec un alpha égal à 0) sont considérés comme étant hors de la surface du nœud, par exemple : les coins évidés dans un rectangle avec des coins arrondis. De même, la plupart des effets graphiques tels que les ombres portées ou les reflets sont généralement considérés comme étant hors du nœud.

    Toutes les parties complètements opaques ainsi que les parties semi-transparentes des formes et groupements sont considérées comme faisant partie de la surface du nœud.

    Comment détecter des événements clavier sur un nœud ?
    Vous devez surcharger l’un des callback de la classe javax.scene.Node.

    • onKeyPressed :function(event :KeyEvent) :Void – Ce callback est appelé quand une touche est en enfoncée.
    • onKeyReleased:function(event :KeyEvent) :Void – Ce callback est appelé quand une touche est en relachée.
    • onKeyType:function(event :KeyEvent) :Void – Ce callback est appelé quand une touche a été saisie.


    Par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var monRectangle = Rectangle {
        x : 10 ;
       y : 10 ;
      width : 100 ;
      height : 100 ;
     
      onKeyType: function(event :KeyEvent) :Void {
         println("Touché enfoncée : {event.code}") ;
      }
    }
    Comment détecter des événements souris sur un nœud ?
    Vous devez surcharger l’un des callback de la classe javax.scene.Node .

    • onMouseClicked :function(event :MouseEvent):Void – Ce callback est appelé si un clic de souris a eut lieu alors qu’elle se trouvait sur la surface du nœud.
    • onMouseDragged :function(event :MouseEvent):Void– Ce callback est appelé si la souris est tirée sur la surface du nœud (et au-delà s’il se poursuit).
    • onMouseEntered :function(event :MouseEvent):Void – Ce callback est appelé si la souris est entrée sur la surface du noeud.
    • onMouseExited :function(event :MouseEvent):Void – Ce callback est appelé si la souris est sortie de la surface du nœud.
    • onMouseMoved:function(event :MouseEvent):Void – Ce callback est appelé si la souris est déplacée sur la surface du nœud.
    • onMousePressed :function(event :MouseEvent):Void – Ce callback est appelé si un bouton de la souris est enfoncé alors qu’elle se trouvait sur la surface du nœud.
    • onMouseReleased :function(event :MouseEvent):Void – Ce callback est appelé si un bouton de la souris est relâché alors qu’elle se trouvait sur la surface du nœud.
    • onMouseWheelMoved :function(event :MouseEvent):Void – Ce callback est appelé si la roulette de la souris a été tournée alors que la souris se trouvait sur la surface du nœud.


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    var monRectangle = Rectangle {
        x : 10 ;
       y : 10 ;
      width : 100 ;
      height : 100 ;
     
      onMouseEntered :function(event :MouseEvent) :Void  {
         println("La souris est entrée dans le rectangle") ;
      }
      onMouseExited:function(event :MouseEvent) :Void  {
         println("La souris est sortie du rectangle") ;
      }
      onMouseMoved :function(event :MouseEvent) :Void  {
         println("La souris se déplace en ({event.x},  {event.y})") ;
      }
    }
    Comment grouper des nœuds ?
    Il existe plusieurs moyens de grouper des nœuds.

    Note : les groupements sont eux-mêmes des nœuds il est donc possible de les mettre dans d’autres groupements.

    Il est possible d’utiliser la classe javafx.scene.Group :
    Code :
    1
    2
    3
    4
     
    var monGroupe = Group {
      content : [momRectangle, monCercle, monComposantSwing]
    }
    Dans un groupe, les composants sont dessinés dans leur ordre d’insertion. Il est possible de modifier cet ordre soit en agissant directement sur le contenu de la séquence content, soit en utilisant les méthodes toBack() ou toFront( ) sur un des nœud qu’il contient Ces deux méthodes changeront donc la profondeur du nœud en question. Il est possible de spécifier via le champ blendMode l’effet graphique à utiliser lorsque deux nœuds se chevauchent. Par défaut un Group a une boite enblobante égale à l’union des boites englobantes des nœuds qu’il contient.

    Il est également possible d’utiliser la classe javafx.scene.layout.HBox qui est une classe dérivée de Group.
    Code :
    1
    2
    3
    4
     
    var maBoiteHorizontale = HBox {
      content : [momRectangle, monCercle, monComposantSwing]
    }
    Dans ce cas les nœuds sont groupés sur une même ligne de la gauche vers la droite. L’appel à toBack() ou toFront( ) déplacera un nœud vers l’extrémité gauche ou droite selon la méthode appelée. En cas de chevauchement, par défaut le nœud le plus à droite chevauche le nœud le plus à gauche.

    Il est également possible d’utiliser la classe javafx.scene.layout.VBox qui est une classe dérivée de Group.
    Code :
    1
    2
    3
    4
     
    var maBoiteVerticale = VBox {
      content : [momRectangle, monCercle, monComposantSwing]
    }
    Dans ce cas les nœuds sont groupés sur une même colonne du haut vers le bas. L’appel à toBack() ou toFront( ) déplacera un nœud vers l’extrémité supérieure ou inférieure selon la méthode appelée. En cas de chevauchement, par défaut le nœud le plus bas chevauche le nœud le plus haut.

    Enfin il est possible d’utiliser une classe dérivée de la classe abstraite javafx.scene.layout.Container. Un conteneur est un groupe dont l’agencement interne est laissé à la charge de son implémentation concrète. Un conteneur a une taille fixée explicitement par le programmeur et tous les nœuds qui sortent de sa boite englobante seront coupés à l’affichage. Il n’existe pas actuellement d’implémentation concrète fournie dans l’API JavaFX 1.0, vous devez donc programmer votre propre mise en page si vous choisissez cette solution.
    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

  18. #18
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Note j'ai ecrit constante pour __DIR__ et __FILE__ mais vu que la doc n'en parle pas il se peut que ce soit des closure. Il faudrait voir si le resultat change en fonction du package ou de la classe dans lequel on les utilise.

    Comment savoir quelle est la classe contenant le script exécuté ?
    Vous devez utiliser la constante globale __FILE__.

    Comment bloquer les événements de la souris ?
    Par défaut, les événements de souris tels que les clics vont traverser tous les nœuds superposés ce qui peut être gênant si vous avez deux nœuds avec des callback personnalisés qui se chevauchent. Cela peut être encore plus problématique si vous avez intégré un composant Swing à votre scène.

    Vous devez mettre le champ blocksMouse de votre nœud à true pour éviter que les événements ne soient propagé aux autres nœuds qui se trouvent sous lui.

    Comment afficher du texte ?
    Vous devez utiliser la classe javafx.scene.text.Text. Text est une classe qui hérite de Node et cet objet peut donc être placé dans une scène et manipulé comme n’importe quel autre nœud.
    Code :
    1
    2
    3
    4
    5
    6
     
    var monTexte = Text {
        x: 10,
        y: 30
        content: "Salut le monde !"
    }
    Contrairement aux nœuds de formes géométriques, les champs x et y sont ici pas les coordonnées du coin supérieur gauche du nœud. Ici, ces coordonnées sont celles de l’extrémité de la ligne de base (baseline) sur laquelle repose le texte.

    Il est possible de spécifier du texte sur plusieurs lignes en séparant chaque ligne de texte par un caractère ‘\n’. Par exemple :
    Code :
    1
    2
    3
    4
    5
    6
     
    var monTexte = Text {
        x: 10,
        y: 30
        content: "Salut le monde !\nCeci est du texte multi-ligne !"
    }
    Comment spécifier la police de caractères ?
    Il est possible de modifier le champ font d’un objet Text en lui donnant une valeur de type javafx.scene.text.Font. Une police peut être crée directement en initialisant ses différents champs de manière similaire au code suivant :
    Code :
    1
    2
    3
    4
    5
     
    var font =  Font {
        name: "Dialog"
        size: 24
        }
    Mais il est également possible d’utiliser les méthodes de fabrique qui sont présentes dans cette classe :
    Code :
    1
    2
     
    var font = Font.font("Dialog", FontWeight.BOLD, FontPosture.ITALIC, 24);
    Ce dernier code créera une police Dialog grasse et italique de taille 24 points.

    Comment afficher une image ?
    Vous devez utiliser la classe javafx.scene.image.ImageView dans lequel vous devez mettre un objet de type javafx.scene.image.Image. ImageView est une classe qui hérite de Node et cet objet peut donc être placé dans une scène et manipulé comme n’importe quel autre nœud.

    Par exemple dans le code suivant le fichier image se trouve dans le même package que le script :
    Code :
    1
    2
    3
    4
    5
    6
    7
     
    var monImage = Image {
            url: "{__DIR__}image.png"
     }
    Var maVue = ImageView {
        image: monImage ;
    }
    Étant donné que la classe Image fonctionne de manière asynchrone le code s’exécutera jusqu’au bout même si l’image n’est pas trouvée mais rien ne sera affiché dans la vue bien sur.

    Comment jouer du son ?
    Vous devez déclarer un objet de type javafx.scene.media.Media qui pointe vers votre fichier sonore et utiliser un javafx.scene.media.MediaPlayer pour le lire.

    Par exemple dans le code suivant le fichier sonore se trouve dans le même package que le script :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    var media = Media{
        source: "{__DIR__}son.wav"        
    }
    var player = MediaPlayer{
        media:media
    }
    player.play();
    Il est possible de mettre le champs autoPlay à true pour que le son soit joué automatiquement mais il semble alors que dans ce cas le lecteur lance une autre Thread ou une Timeline et que le script ne se termine pas.

    Si le fichier sonore n’est pas trouvé des exceptions seront levées sur la console mais comme la classe Media fonctionne de manière asynchrone le code s’exécutera jusqu’au bout (mais aucun son ne sera joué bien sur).
    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

  19. #19
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Comment utiliser l’API Java 1.6 avec JavaFX 1.0 ou 1.1 ?
    Par défaut les SDK de JavaFX 1.0 et 1.1, ainsi que les modules NetBeans permettant de faire du JavaFX, sont distribués avec une version allégée de rt.jar (le JAR contenant toute l’API standard Java) ce qui permet de compiler du JavaFX sans devoir disposer du SDK Java (JDK). Ce fichier se trouve dans <chemin d’installation du javaFX SDK >/lib/desktop/rt15.jar ou dans <chemin d’installation de NetBeans>/javafx2/javafx-sdk/lib/desktop/rt15.jar

    Le problème est que, comme son nom l’indique, ce fichier contient en fait l’API Java 1.5 ce qui empêche d’utiliser l’API Java 1.6 avec les outils de développement actuels. Attention, cela empêche uniquement la compilation du code utilisant l’API 1.6. Lors de l’exécution, JavaFX utilisera la dernière version de Java présente sur votre système de toute manière.

    La solution à ce problème consiste en :
    1. Renommer le fichier rt15.jar avec un autre nom de manière à en faire une sauvegarde. Ce fichier fait aux alentours de 4 Mo.
    2. Aller chercher le fichier rt.jar dans votre distribution du JDK ou du JRE 1.6 (<chemin d’installation du JDK>/jre/lib/rt.jar ou <chemin d’installation du JRE>/lib/rt.jar). Ce fichier fait entre 42 et 47 Mo.
    3. Copiez-le puis collez-le dans le répertoire approprié de votre installation du SDK de JavaFX
    4. Renommez-le en rt15.jar


    Comment étendre des interfaces Java ou classes Java en JavaFX ?
    Pour étendre des interfaces, classes abstraites ou classes Java en JavaFX, vous devez utiliser le nom-clé extends exactement comme si vous étendiez des classes écrites en JavaFX. Cependant pour connaître les méthodes que vous devez implémenter, vous devrez vous référer à la documentation de l’API Java (javadoc) qui est disponible en ligne aux URL suivantes :

    Vous devrez faire attention à la différence de syntaxe qui existe entre les langages Java et JavaFX lorsque vous êtes amenés à réaliser ce genre d’opérations. Si vous ne connaissez pas le langage Java, n’hésitez pas à aller jeter un coup d’œil à la FAQ, aux tutoriels ou dans les forums liés à ce langage.

    Il est ainsi possible de créer une classe JavaFX qui implémente un écouteur Java pour répondre à des événements divers. Par exemple le code suivant affiche un JButton dans une scène (ce code est un exemple, n’oubliez pas que JavaFX fourni le nœud javafx.ext.swing.SwingButton pour éviter de faire ce genre de choses manuellement) :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package test;
     
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.text.Text;
    import javafx.scene.text.Font;
     
     
     
    /**
     * @author fabriceb
     */
     
    Stage {
        title: "Test d'ecouteur"
        width: 250
        height: 80
        scene: Scene {
            content: ButtonNode {
            }
        }
    }
    Code :
    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
     
    package test;
     
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javafx.ext.swing.SwingComponent;
    import javafx.scene.CustomNode;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javax.swing.JButton;
     
    /**
     * @author fabriceb
     */
     
    public class ButtonNode extends CustomNode, ActionListener {
        var button: JButton;
        var buttonNode: SwingComponent;
        /**
        * {@inheritDoc}
         */
        public override function create(): Node {
            button = new JButton("Salut !");
            button.addActionListener(this);
            buttonNode = SwingComponent.wrap(button);
            return Group {
                content: [buttonNode]
            };
        }
    Ici notre classe ButtonNode hérite de l’interface java.awt.event.ActionListener. D’après sa page de documentation, cette interface contient une unique méthode qui est appelée lorsque l’utilisateur clique sur le bouton :
    Code :
    public void actionPerformed(ActionEvent event) ;
    Pour étendre correctement cette interface notre classe se doit de définir une fonction avec une signature appropriée mais en JavaFX. La signature de la fonction devient donc :
    Code :
    override public function actionPerformed(e:ActionEvent):Void;
    Ainsi, si nous écrivons :
    Code :
    1
    2
    3
    4
    5
    6
    7
     
        /**
        * {@inheritDoc}
         */
        override public function actionPerformed(e:ActionEvent):Void {
            FX.exit();
        }
    Désormais notre programme se terminera lorsque nous cliquons sur le bouton.

    Il en va de même pour toutes les signatures de méthodes définies dans des interfaces Java, toutes les méthodes abstraites définies dans des classes abstraites Java que vous serez amené à définir ainsi que toute les méthodes définies dans des classes Java que vous serez amené à surcharger dans vos classes JavaFX.

    Comment utiliser des Generics ?
    Le langage JavaFX ne supporte pas les Generics pour le moment, vous devez donc utiliser les classes Java utilisant des générics sans spécifier de type. Dans les faits c’est comme si leur type générique était le type java.lang.Object. Si vous avez besoin de récupérer un type particulier il vous faudra donc le caster en utilisant le mot-clé as. Étant donné que vous perdez le contrôle supplémentaire que vous offre le support des Generics au moment de la compilation, vous devez être très attentif lors de vos casts.

    Ainsi, il est impossible de définir :
    Code :
    1
    2
    3
    4
    5
    6
     
    import java.util.HashMap;
     
    var jfxMap = new HashMap<String, Integer>();
    jfxMap.put("1", 1);
    var result1:Integer = jfxMap.get("1");
    Ce code ne compile pas et génère l’erreur suivante : Java style generics are not currently supported in JavaFX, so you cannot use them here.

    Vous devrez utiliser le code suivant à la place :
    Code :
    1
    2
    3
    4
    5
    6
     
    import java.util.HashMap;
     
    var jfxMap = new HashMap();
    jfxMap.put("1", 1);
    var result1:Integer = jfxMap.get("1") as Integer;
    Dans ce code, les types génériques sont omis. Cependant ce code peut faire l’objet d’erreurs si on se trompe sur le type de la valeur retournée.

    Ainsi le code suivant compilera sans aucun problème mais générera une ClassCastException lors de l’exécution :
    Code :
    var result1: String = jfxMap.get("1") as String;
    Si vous avez un réel besoin d’un contrôle sur le type, vous pouvez cependant définir du code dans une classe Java dans votre projet JavaFX. Par exemple dans le fichier JavaMap.java :
    Code :
    1
    2
    3
    4
    5
     
    import java.util.HashMap;
     
    public class JavaMap extends HashMap<String, Integer> {
    }
    Puis dans notre script :

    Code :
    1
    2
    3
    4
     
    var jMap = new JavaMap();
    jMap.put("1", 1);
    var result2: Integer = jMap.get("1");
    Dans ce cas, le contrôle des types est forcé par leur déclaration dans les Generics utilisés pour la définition de la classe Java et la variable résult2 ne peut être que d’un type numérique compatible avec Integer.

    Par exemple, le code suivant ne compilera pas :
    Code :
    1
    2
     
    var result2: String = jMap.get("1");
    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

  20. #20
    Modérateur
    Avatar de bouye
    Homme Profil pro Fabrice Bouyé
    Développeur Java
    Inscrit en
    août 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabrice Bouyé
    Âge : 38
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2005
    Messages : 4 485
    Points : 9 173
    Points
    9 173

    Par défaut

    Comment utiliser l’interpréteur de script JavaFX dans le ScriptingEngine (Java 6) ?
    Le moteur de scripting fourni depuis la version 1.6 de Java est capable d’interpréter du code écrit dans un language de scripting. Par défaut, le seul moteur fourni avec la JVM est le moteur capable d'interpréter le langage ECMAScript (JavaScript).

    Le SDK de JavaFX fourni les classes nécessaires à l’ajout d’un interpréteur pour le langage JavaFX. Cependant, par défaut, tant en Java qu’en JavaFX, l’interpréteur n’est pas ajouté au CLASSPATH de la JVM. Ainsi les lignes de code suivantes listent les moteurs de scripts disponibles dans la JVM :

    • En JavaFX :
      Code JavaFX :
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
       
      import javax.script.ScriptEngineManager;
       
      var scriptEngineManager = new ScriptEngineManager();
      var factories = scriptEngineManager.getEngineFactories();
      var factoryIterator = factories.iterator();
      println("Available engines:");
      while (factoryIterator.hasNext()){
        var factory = factoryIterator.next() as ScriptEngineFactory;
        println("Engine Name: {factory.getEngineName()} / Engine Language: {factory.getLanguageName()}");
      }
    • En Java, dans un fichier Test.java :

      Code Java :
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
       
      import java.util.List;
      import java.util.Iterator;
      import javax.script.ScriptEngineFactory;
      import javax.script.ScriptEngineManager;
       
      public class Test {
       
          /**
           * @param args the command line arguments
           */
          public static void main(String[] args) throws ScriptException {
              ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
              List<ScriptEngineFactory> factories = scriptEngineManager.getEngineFactories();
              Iterator<ScriptEngineFactory> factoryIterator = factories.iterator();
              System.out.println("Available engines:");
              while (factoryIterator.hasNext()) {
                  ScriptEngineFactory factory = factoryIterator.next();
                  System.out.println("Engine Name: " + factory.getEngineName() + " / Engine Language: " + factory.getLanguageName() + "");
              }
          }
      }

    Sans modifier le CLASSPATH, ce code affiche le résultat suivant qui indique bien que seul le moteur ECMAScript est supporté :
    Code :
    1
    2
    3
     
    Available engines:
    Engine Name: Mozilla Rhino / Engine Language: ECMAScript
    Pour obtenir un moteur JavaFX fonctionnel, il suffit rajouter le fichier javafxc.jar au CLASSPATH, par exemple dans la liste des dépendances de votre projet. Dans les SDK JavaFX 1.0 et 1.1, ce fichier se trouve à l’emplacement suivant : <chemin d’installation du SDK de JavaFX >/lib/shared/javafxc.jar

    La seul chose à faire est de l’ajouter au CLASSPATH, et désormais le code précédent listera le moteur de script JavaFX en plus de celui d’ECMAScript :
    Code :
    1
    2
    3
    4
     
    Available engines:
    Engine Name: Mozilla Rhino / Engine Language: ECMAScript
    Engine Name: JavaFX Script Engine / Engine Language: javafx
    Comment instancier et utiliser un interpréteur JavaFX en JavaFX ?
    Une fois le moteur de script rajouté à la JVM, il est possible de récupérer un interpréteur pour JavaFX en faisant :
    Code :
    1
    2
     
    var scriptEngine = scriptEngineManager.getEngineByExtension("fx");
    Ou :
    Code :
    1
    2
     
    var scriptEngine = scriptEngineManager.getEngineByName ("javafx");
    Attention ! Si le moteur de script n’a pas été correctement rajouté, scriptEngine sera à null.

    Il nous est à présent possible d’interpréter du JavaFX dans du JavaFX. Par exemple le code suivant ouvrira une fenêtre :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    var text = "import javafx.stage.*;\n\nStage \{\n\twidth:100;\n\theight:100;\n\ttitle:\"Test\"\n\}";
    try {	
          var returnValue = scriptEngine.eval(text);
    }
    catch (e: javax.script.ScriptException) {
      e.printStackTrace() ;
    }
    Note: ici les caractères '{' et '}' sont échappés grâce à un '\' pour éviter d’être interprétés comme définissant les limites d’une string expression par le compilateur. Ceci est uniquement valable pour une chaine de caractères définie en JavaFX.

    Comment instancier et utiliser un interpréteur JavaFX en Java ?
    Une fois le moteur de script rajouté à la JVM, il est possible de récupérer un interpréteur pour JavaFX en faisant :
    Code :
    1
    2
     
    ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("fx");
    Ou :
    Code :
    1
    2
     
    ScriptEngine scriptEngine = scriptEngineManager. getEngineByName ("javafx");
    Attention ! Si le moteur de script n’a pas été correctement rajouté, scriptEngine sera à null.
    De plus, pour pouvoir utiliser l’API JavaFX, il faudra rajouter les fichiers JARs de l’API JavaFX ainsi que ceux du profile utilisé dans le CLASSPATH, par exemple en modifiant les dépendances de votre projet. Sinon par défaut vous ne pourrez utiliser que l’API Java. Dans JavaFX 1.0 et 1.1, ces fichiers sont localisés dans le répertoire <chemin d’installation du SDK de JavaFX >/lib/ ainsi que ses sous-répertoires.

    Il nous est à présent possible d’interpréter du JavaFX dans du Java. Par exemple le code suivant ouvrira une fenêtre :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    String text = "import javafx.stage.*;\n\nStage {\n\twidth:100;\n\theight:100;\n\ttitle:\"Test\"\n}";                
    try {
      Object returnValue = scriptEngine.eval(text);
    }
    catch (ScriptException e) {
      e.printStackTrace();
    }
    Note: ici les caractères '{' et '}' ne sont pas échappés puisque notre chaine de caractère est définie en Java et que les string expression n'existent pas en Java.
    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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •