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

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

JavaFX Discussion :

Comprendre l'API Cell de JavaFX pour customiser les contrôles de base, un tutoriel de Fabrice Bouyé


Sujet :

JavaFX

  1. #1
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut Comprendre l'API Cell de JavaFX pour customiser les contrôles de base, un tutoriel de Fabrice Bouyé
    Bonjour, je vous propose un second article concernant JavaFX, cette fois-ci sur l'utilisation de l'API Cell qui couvre les contrôles virtualisés (ListView, TreeView, etc.).

    http://fabrice-bouye.developpez.com/...ls/javafxcell/

    Vous pouvez profiter de ce message pour partager vos commentaires. Cet article a été commencé sous JavaFX 2.2 il y a plus d'un an et j'ai ensuite mis à jour certaines parties pour JavaFX 8 donc, surtout, n’hésitez pas à m'indiquer toutes erreurs, omissions ou encore des éventuels anomalies.
    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

  2. #2
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    La comparaison des performances entre Swing n’est ni logique, ni juste. Le seul moyen de connaître la taille globale d’un composant composite telle qu’une liste est de solliciter le CellRenderer pour chacun de ses éléments. C’est pourquoi il y a 3000 appels au démarrage (3000 x N en fait) et uniquement au démarrage ! Si on utilise l’ascenseur, par exemple, seuls une poignée de CellRenderer sont sollicités. Soulignons au passage que le coût d’un CellRenderer n’est pas nécessairement très important si on les construit intelligemment et qu’on a compris que, la plupart du temps, ils ne servent qu’à fournir des dimensions et non à réaliser le moindre rendu. Néanmoins, si on a vraiment trop d’éléments ou des CellRenderers complexes, l’optimisation proposée par l’API Swing depuis le début est d’accepter le compromis d’avoir des cellules de taille fixe :

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    list.setFixedCellHeight(16);
    list.setFixedCellWidth(500);

    Avec ces 2 contraintes, il n’y a plus que 30 x 2 sollicitations de CellRenderer au premier affichage.

    Je ne connais pas l’API de JavaFX, mais j’imagine que ses concepteurs ont simplement opté pour des comportements par défaut différents.

  3. #3
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Ils ont opté pour des optimisations et celle-ci est la plus importante par rapport à Swing : on ne crée pas 36.000 lignes ! C'est ce qui définit l'architecture des contrôles virtualisés :

    • Swing : un tampon qu'on transforme pour chaque ligne, appels à chaque défilements, etc.
    • JavaFX : nombre de cellules visibles + 1-2. On estime la hauteur totale en fonction de ce qui est visible plutôt que de la calculer à chaque fois en passant sur chaque ligne.


    Bémol sur ce que je viens de dire : CheckBox implémente elle toutes ses cellules une première fois lors de son affichage (ce qui est assez pénible d'ailleurs), non pas pour trouver sa hauteur mais... la largeur de son menu popup.

    La stratégie est complètement différente et repose bien sur ce point particulier et pas un autre ! Donc impossible d'expliquer comment ça marche sans le soulever

    Par contre, tout n'est pas optimisé encore à 100% dans JavaFX : quand on réduit la taille du composant on ne se débarrasse pas des cellules en trop, elles restent dans le pool de cellules disponibles.
    JavaFX 8 a apporté d'autres optimisations comme introduire la possibilité de définir une hauteur fixe de cellule ce qui permet d'éviter de faire le layout pour le calculer.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

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

  4. #4
    Membre habitué
    Inscrit en
    Septembre 2002
    Messages
    233
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 233
    Points : 131
    Points
    131
    Par défaut
    Merci pour ce tutorial très complet sur un sujet pas évident.

    Par contre je n'ai pas trouvé pour les tableview si il était possible de désactiver la sélection d'une ligne via le curseur ? J'ai essayé en changeant le selectionModel, en positionnant editable à false.

    Est ce possible ?

    Merci

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    J'ai fait des essais pas concluant en essayant de changer le [CODEinline]RowFactory [/CODECODEinline] mais ca ne donne rien. Donc probablement ecrivant un nouveau SelectionModel (s'inspirer de la classe interne statique package protected TableView.TableViewArrayListSelectionModel visible en allant sur le mercurial contenant les sources) et en essayant de surcharger une des methodes de sélection.

    EDIT 1 - Ah retour sur RowFactory mais en utilisant la propriete Disable, ca fonctionne bien mieux !!!!!!

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    tableView.setRowFactory((TableView<Person> param) -> new TableRow<Person>() {
        {
            disableProperty().bind(indexProperty().isEqualTo(1));
        }
    });
    Du coup, on ne peut plus la sélectionner la 2nde ligne (celle a l'index 1), ni interagir avec les éléments qu'elle contient (une de colonnes dans mon test contient des checkbox).
    On peut toujours sélectionner et utiliser les autres lignes sans soucis.
    Et ensuite tu peux utiliser les CSS pour éviter que l'apparence soit différente.

    EDIT 2 - il reste cependant possible de sélectionner la ligne au clavier
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

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

  6. #6
    Membre habitué
    Inscrit en
    Septembre 2002
    Messages
    233
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 233
    Points : 131
    Points
    131
    Par défaut
    Merci pour tes recherches, il y aura peut etre un moyen plus simple dans les prochaines versions du jdk.

  7. #7
    Futur Membre du Club
    Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Merci pour le tuto ( dieu sait que ça manque en FR )
    J'espère que je suis dans la bonne zone pour la réponse :

    le contexte :
    j'ai besoin de connaitre la hauteur d'une tableView peuplée dynamiquement afin de pouvoir l'afficher en entier sans scrollbar. (le document affiché est imprimé)

    Le problème : a travers le css les hauteurs de texte sont aléatoires

    mis a part en fixant les hauteurs de cellules et en bindant la hauteur de la table sur la somme des hauteurs des cellules + header , je ne trouve pas de moyen d'affecter la bonne hauteur.
    en effet en utilisant les row factory et les cell factory je n'ai aucun moyen de récupérer la hauteur des lignes affectée ( ou des cellules , qui sont des Labelled).

    pour la rowfactory si je veux faire un setPrefHeight (ou min ou max) ça m'affecte bien la hauteur... mais si je fait un get : j'ai -1 pour les valeur min pref et max et du coup 0 pour getHeight().

    Pour commencer j'ai du mal a comprendre correctement les factory ( j'ai pas encore trouvé des tuto en fr qui répondent a mes attentes), j'ai appliqué bêtement les tuto (EN) pour l’édition, je vois comment ça fonctionne mais... je sens qu'il me manque quelque chose.

    N’hésitez pas a me fustiger pour plus d'infos.

    Merci encore.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Ingénieur génie chimique
    Inscrit en
    Mai 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Corée

    Informations professionnelles :
    Activité : Ingénieur génie chimique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2015
    Messages : 3
    Points : 5
    Points
    5
    Par défaut Bravo
    Bonjour,

    Merci beaucoup pour ce tutoriel de pro.
    Je suis programmateur java amateur et j'apprécie beaucoup ce tutoriel qui donne des explications fouillées (pas toujours facile de comprendre les javadocs) et montre par la même occasions de jolis codes java, avec notamment la démonstration de l'utilisation de fichiers FXML.

  9. #9
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Mais de rien. Par contre, étant donné que le didacticiel sur FXML n'avait pas encore été publié à l'époque, je ne me suis pas penché sur la déclaration des cell factory directement dans le FXML. C'est possible mais ne n'ai pas vraiment pratiqué donc, ça reste largement inexploré et non-testé de mon coté.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

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

  10. #10
    Futur Membre du Club
    Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 4
    Points : 6
    Points
    6
    Par défaut Row factory , connaitre la hauteur des lignes.
    Bonjour,
    c'est juste une info supplémentaire concernant mon post sur les hauteurs de cellules(lignes) des table views .
    Dans l'idée je sur en train de faire un editeur friendly user de documents destinés a l'impression. Hors ces documents comportent une liste qui a une hauteur générale variable non connue a l'avance, et évidement toutes les lignes n'ont pas la même hauteur.
    Destiné a l'impression je connais ma hauteur max.
    L'idée étant de savoir où je dois couper ma liste pour le report de page (sachant que je peux pas diviser le nombre d’éléments par le nombre de pages):
    Le calcul de la hauteur d'un noeud (Node.getHeight()) se fait par rapport au noeud parent, il faut donc affecter la tableview a son parent , et afficher le stage.
    ensuite on place un écouteur sur la hauteur de la tableview qui va ajouter une ligne une fois que la hauteur change tant que l'on a pas atteint la hauteur max.
    si on dépasse la hauteur max on supprime la dernière ligne, on fait le report de page et on recommence.
    Vu que tout est affiché pendant la création, on voit les lignes s'ajouter au fur et a mesure sur le noeud parent, ainsi que toute la création dynamique.

    La tableView n'est pas adaptée pour mon utilisation , j'ai donc préféré une gridPane :
    Pour faire le calcul de mes report de page, je lance un stage avec un pane de hauteur non fixe:
    Je créé ma gridpane avec un GridPane.addRow(index,Collection... Node).
    Comme pour la tableview je place un écouteur sur la hauteur de ma gridpane et je lui met un setVisible(false)
    dès que j'atteins ma hauteur max , Je place ma liste dans une HashMap<Integer,<List<Item>> (numéro de page et liste tronquée a l'index adéquat pour rentrer dans la page)
    arrivé a la fin, j'ai, dans ma HashMap, la représentation de l'affichage.
    J'applique la même procédure pour chaque éléments qui doivent se comporter pareil le tout, bien caché de l'utilisateur.
    Lancé dans un thread, pendant la création du document j'ai mis une petite progressBar avec une invitation d'attente.
    Une fois a 100% je supprime les nœuds qui m'ont servis a créer mon document, et j'ai plus qu'a l'afficher.

    c'est vrai que c'est du bidouillage. Mais en attendant que je découvre comment le faire correctement c'est la seule solution que j'ai trouver pour regler mon problème.

    -- Fin de l'info.

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/01/2015, 23h59
  2. Réponses: 0
    Dernier message: 09/09/2011, 10h11

Partager

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