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

Composants Java Discussion :

FlowLayout dans JScrollPane


Sujet :

Composants Java

  1. #1
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Par défaut FlowLayout dans JScrollPane
    Bonjour,
    J'ai un JPanel avec un FlowLayout que je remplis de JLabel. Les labels sont bien répartis dans toute la place disponible. Ce panel est dans un GridBagLayout. Donc dans certains cas, il n'y a pas assez de place pour tout afficher et j'ai donc décider de mettre un JScrollPane (en fait un Jidesoft.SimpleScrollPane).

    Problème, le FlowLayout n'utilise maintenant plus tout la hauteur disponible, puisque le viewport du scrollpane lui donne une largeur infinie pour se peindre. Tous mes labels sont donc sur une seule ligne.
    Je voudrais que le layout continue à utiliser toute la hauteur possible et dépasse de la largeur du viewport uniquement si nécessaire.

    Dans un 1er temps j'ai écrit un nouveau LayoutManager basé sur le FlowLayout qui utilise la dimension du viewport comme base plutôt que la largeur du panel. C'est une 1ère approximation de ce que je veux en final qui fonctionne comme je m'y attendais. Les labels sont uniquement disposés sur la largeur du viewport, et dépassent verticalement si nécessaire.

    Seul problème dans cette 1ère version est que la scrollbar horizontale apparaît toujours, car le panel semble avoir conservé la même largeur que si tous les labels étaient mis l'un à côté de l'autre.

    D'où ma question dans chaîne du layout des composants:
    comment est déterminée la largeur du panel ? Est-ce que cela a avoir avec les méthodes preferredLayoutSize(Container target) et minimumLayoutSize(Container target) ?
    (Est-ce qu'il existe une doc qui explicite un peu cette chaîne ? Je m'y perds...)

    Merci,

    Laurent

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par lvr Voir le message
    D'où ma question dans chaîne du layout des composants:
    comment est déterminée la largeur du panel ? Est-ce que cela a avoir avec les méthodes preferredLayoutSize(Container target) et minimumLayoutSize(Container target) ?
    (Est-ce qu'il existe une doc qui explicite un peu cette chaîne ? Je m'y perds...)
    En fait ce n'est pas si simple car chaque placement/taille de composant est lié à un layout-manager, et chaque layout-manager peut prendre en compte les valeurs de minimum/maximum/preferredSize ou pas...


    Dans le cas d'un JScrollPane standard, l'objectif est d'afficher le composant au mieux donc c'est la preferredSize qui est utilisé. Il faut donc que ton Layout renseigne correctement cette taille.


    Tu pourras trouver un exemple ici : http://www.developpez.net/forums/d61...s/#post3634553


    a++

  3. #3
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    En fait ce n'est pas si simple car chaque placement/taille de composant est lié à un layout-manager, et chaque layout-manager peut prendre en compte les valeurs de minimum/maximum/preferredSize ou pas...
    Ce sont ces "ou pas..." qui rendent parfois difficile de faire de beaux panneaux sans perdre des heures à chipoter
    Citation Envoyé par adiGuba Voir le message
    Tu pourras trouver un exemple ici : http://www.developpez.net/forums/d61...s/#post3634553
    C'est vers ça que je me dirigeais... mais dans le mauvais sens.
    Plutôt que d'adapter la méthodes layout(target) et je devrais exclusivement adapter les minimum/preferredLayoutSize comme tu suggères puis laisser le layout(parent) travailler sur base de la nouvelle taille donnée par la scrollpane.
    Merci

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lvr Voir le message
    Ce sont ces "ou pas..." qui rendent parfois difficile de faire de beaux panneaux sans perdre des heures à chipoter
    Oui mais en même temps c'est logique puisque c'est le layout qui décide de la manière dont il va représenter les composants. Il prend donc ses décisions selon les critères de son choix, pour arriver au rendu qu'il souhaite.

    Mais c'est clair que ce n'est pas toujours évident...

    a++

  5. #5
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 27
    Par défaut
    Salut,

    J'ai du faire face au même problème que toi il y a quelques temps. Après mes recherches, j'ai trouvé cette classe qui marche très bien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    import java.awt.*;
     
    public class ModifiedFlowLayout extends FlowLayout
    {
        public ModifiedFlowLayout()
        {
            super();
        }
     
        public ModifiedFlowLayout(int align)
        {
            super(align);
        }
     
        public ModifiedFlowLayout(int align, int hgap, int vgap)
        {
            super(align, hgap, vgap);
        }
     
        public Dimension minimumLayoutSize(Container target)
        {
            return computeSize(target, false);
        }
     
        public Dimension preferredLayoutSize(Container target)
        {
            return computeSize(target, true);
        }
     
        private Dimension computeSize(Container target, boolean minimum)
        {
            synchronized (target.getTreeLock())
            {
                int hgap = getHgap();
                int vgap = getVgap();
                int w = target.getWidth();
     
           // Let this behave like a regular FlowLayout (single row)
           // if the container hasn't been assigned any size yet    
                if (w == 0)
                    w = Integer.MAX_VALUE;
     
                Insets insets = target.getInsets();
                if (insets == null)
                    insets = new Insets(0, 0, 0, 0);
                int reqdWidth = 0;
     
                int maxwidth = w - (insets.left + insets.right + hgap * 2);
                int n = target.getComponentCount();
                int x = 0;
                int y = insets.top;
                int rowHeight = 0;
     
                for (int i = 0; i < n; i++)
                {
                    Component c = target.getComponent(i);
                    if (c.isVisible())
                    {
                        Dimension d =
                            minimum ? c.getMinimumSize() :     
                     c.getPreferredSize();
                        if ((x == 0) || ((x + d.width) <= maxwidth))
                        {
                            if (x > 0)
                            {
                                x += hgap;
                            }
                            x += d.width;
                            rowHeight = Math.max(rowHeight, d.height);
                        } else
                        {
                            x = d.width;
                            y += vgap + rowHeight;
                            rowHeight = d.height;
                        }
                        reqdWidth = Math.max(reqdWidth, x);
                    }
                }
                y += rowHeight;
                return new Dimension(reqdWidth+insets.left+insets.right, y);
            }
        }
    }

  6. #6
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Par défaut
    Lamarios, adiGuba, Merci.
    J'ai implémenté une solution similaire hier soir (objectif: ne jamais avoir de scrollbar verticale, mais tout de même utiliser toute la hauteur disponible) et cela marche presque nickel.

    En static, les composants sont correctement positionnés.

    Par contre quand je redimensionne le panneau qui contient le scrollpane (le scrollpane est dans un panneau d'un Jsplittedpane, panneau géré par un GridBagLayout), les éléments dans scrollpane ne sont pas redisposés.

    Comment faire pour que lorsque je déplace la barre de séparation de mon splittedpane et que le gridbaglayout réassigne des dimensions à mes composants, tout le process du layout de mon SuperFlowLayout soit relancé ?
    Est-ce qu'il faut que je détecte le déplacement de la barre du splittedpane pour faire un validetree() ou quelque chose comme ça ?

  7. #7
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Je viens de tester et en effet j'obtiens le même comportement.

    Il semblerais que le JScrollPane lorsque tu définis une scrollbar avec SCROLLBAR_NEVER pour ne pas l'afficher, le JScrollPane ne cherche pas à recalculer sa taille dans le sens indiqué, et donc ne revérifies pas la taille 'preferred'.

    Il faut laisser le scrollbar horizontal à SCROLLBAR_AS_NEEDED afin qu'il recalcule la largeur à chaque déplacement.


    a++

  8. #8
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Par défaut
    Ma scrollbar horizontale est "AS_NEEDED". Mais je n'utilise pas le JScrollPane original mais SimpleScrollPane de chez Jide Software. Je vais tester avec un scrollpane normal et si ça marche, le problème est dans le SimpleScrollPane. Je ferai remonter cela chez Jide.
    Je te tiens au courant. Merci.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 19
    Par défaut
    Je suis aussi preneur de la solution (si tant est qu'elle existe !)

    Mon besoin plus ou moins identique : affichage d'un tableau de données dynamiques (sans scrollbars), avec 3 modes possibles :
    - resizing manuel des colonnes,
    - resizing automatique en adaptant la largeur de chaque colonne aux données qu'elle contient (ça, ça marche, car indépendant de la largeur de la fenêtre),
    - resizing automatique en adaptant la largeur du tableau à celle de la fenêtre : ça marche de façon statique, sauf que quand je redimensionne ma fenêtre, je ne parviens pas à récupérer la nouvelle taille du "composant" dans lequel est affiché mon tableau.

    J'ai aussi essayé : tableau dans JScrollPane dans JPanel, puis jPanel.getWidth(). Cette valeur peut grandir, mais ne descend jamais au dessous de la preferredSize du JScrollPane. Et si je n'affecte pas de preferredSize à ma scrollPane, les résultats deviennent catastrophiques...

    Pour info, je n'utilise que des GridBagLayout !

  10. #10
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    @Belo Euh, et tu as essayé avec une JTable sinon? C'est un peu prévu pour les tableaux de données dynamique comme composant à la base quand même...

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 19
    Par défaut
    Oui , j'utilise en fait 2 JTable. La raison pour laquelle j'emploie des GridBagLayout est que je souhaite aussi placer 3 boutons à droite d'une des tables (qui fait 2 lignes, l'autre étant en dessous et censée occuper tout l'espace horizontal), dont :
    ajuster la largeur des colonnes au contenu (pour les 2 tables),
    ajuster la largeur totale des colonnes à la fenêtre (pour les 2 tables aussi).

    J'ai par ailleurs placé un listener sur les headers pour détecter un double-click et ajuster la largeur de la colonne correspondante au contenu. Comme il y a beaucoup de colonnes, et parfois peu de place (sur un p'tit écran), je souhaite proposer à l'utilisateur de n'agrandir que les colonnes qui l'intéressent (elles contiennent des données dynamiques faisant référence à de l'animation graphique).C'est donc pour cela que j'ai désactivé le resizing automatique.

    Je ne comprends donc toujours pas pourquoi mon layout ne redimensionne pas la taille des scrollPane lorsque je redimensionne la fenêtre.

  12. #12
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    As tu bien placé le FILL de tes GridBagConstraints à HORIZONTAL ou à BOTH?
    Quelle est la valeur de tes weightx et weighty?

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 19
    Par défaut
    Oui, le fill est bien positionné (à HORIZONTAL). Les weightx et weighty valent respectivement 1F et 0F.
    J'encapsule mes boutons (situés à droite du tableau) dans un JPanel, de fill NONE et de weightx et weighty à 0F.

    Lorsque je réduis la largeur de ma fenêtre à la souris, donc, les boutons situés à droite ne se déplacent pas avec la bordure... sauf que... j'ai oublié un point de détail qui a peut-être son importance () :
    mes JTable sont dans des JScrollPane avec des scrollBars à NEVER, tandis que tous mes composants (les 2 tableaux + les boutons sont dans un même super JScrollPane, qui lui a ses scrollBars à AS_NEEDED) : c'est pour n'avoir qu'une seule scrollbar. Le problème semble donc encore se poser un cran plus haut .
    Je vais contrôler la valeur de width() de ce super JScrollPane, et je reviens pour vous dire ce qu'il en est...

    En tout cas, le problème semble être le même que le problème de redimensionnement de la fenêtre avec un gridBag gérant une scrollPane qu'avait lvr :

    En static, les composants sont correctement positionnés.

    Par contre quand je redimensionne le panneau qui contient le scrollpane (le scrollpane est dans un panneau d'un Jsplittedpane, panneau géré par un GridBagLayout), les éléments dans scrollpane ne sont pas redisposés.

    Comment faire pour que lorsque je déplace la barre de séparation de mon splittedpane et que le gridbaglayout réassigne des dimensions à mes composants, tout le process du layout de mon SuperFlowLayout soit relancé ?
    l faudrait peut-être que j'essaye avec un autre layout que le gridBag.
    Je vais donc tester d'autres layouts... Sinon, à la rigueur, je supprimerai mes boutons et j'utiliserai mes JTable dans un mode un peu plus "standard"...

  14. #14
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Par défaut
    Citation Envoyé par BeLO Voir le message
    En tout cas, le problème semble être le même que le problème de redimensionnement de la fenêtre avec un gridBag gérant une scrollPane qu'avait lvr :
    En static, les composants sont correctement positionnés.

    Par contre quand je redimensionne le panneau qui contient le scrollpane (le scrollpane est dans un panneau d'un Jsplittedpane, panneau géré par un GridBagLayout), les éléments dans scrollpane ne sont pas redisposés.

    Comment faire pour que lorsque je déplace la barre de séparation de mon splittedpane et que le gridbaglayout réassigne des dimensions à mes composants, tout le process du layout de mon SuperFlowLayout soit relancé ?
    Mon problème n'était pas un problème de Swing mais une erreur dans l'algorithme du getPreferedSize de mon SuperFlowLayout.

    Mon expérience m'a montré que tout n'est pas faisable avec un GridBagLayout. Par exemple tu peux avoir des contraintes qui le perturbe.
    Ce que je fais dans certains cas, c'est extraire du GridBag une ligne composée de plusieurs colonnes et la transformer en panel régis par son propre layout, puis re-mettre ce panel dans le GridBag sur toute sa largeur avec un fill Horizontal. Ca m'a déjà sauvé la vie quand j'avais beau mettre les poids au mieux, mais que le gridbag se perdait dans certains cas.
    Je te conseille aussi le BoxLayout de chez JideSoftware. C'est comme un BoxLayout de Swing si ce n'est que tu peux imposer que certains éléments ne soient pas redimensionnés automatiquement (pratique pour une zone de boutons, de libellés, ...)

  15. #15
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Ou aller chercher du coté de vrais bons layouts comme le FomLayout JGoodies ou le MigLayout par exemple.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 19
    Par défaut
    Merci sinok,

    : T'es pourrave, oui, t'es pas pourrave...


    Ou aller chercher du coté de vrais bons layouts comme le FomLayout JGoodies ou le MigLayout par exemple.
    Pas très sympa pour Sun... en tout cas, pour l'info !

    J'ai donc rapidement parcouru des docs qui concernent les layouts que tu m'as retransmis. Je n'ai certainement pas tout saisi de la portée de tels layouts, mais je m'étonne néanmoins de la critique que l'on peut émettre au sujet du GridBagLayout. C'est tout de même marrant que celui-ci ne produise pas les résultats escomptés.

    Alors, à moins que je me démerde mal, mon layout adopte des comportements parfois étranges, ce qui laisse supposer qu'il comporte des bugs... Tout de même, depuis l'temps qu'ça existe, ça devrait être corrigé, non ?

    Petit aparté :
    À cet effet, j'ai un autre problème avec les gridBagLayout, mais j'ouvrirai peut-être une autre discussion. Juste pour info, comme ça, c'est dans le cadre de la réalisation d'un JTextField (correspondant à un champ de saisie, pas de retour chariot, et pas de scrollbars), mais qui aurait en plus les capacités d'une JTextArea à formater le texte (gras, italique, couleurs, ...)
    Est-ce que ça existe déjà quelque part, parce que j'ai rajouté des "contraintes" sur une JTextArea, mais ça semble foutre le bronx dans le layout...

    Encore merci pour vos réponses à tous !

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

Discussions similaires

  1. Défilement automatique JTable dans JscrollPane
    Par jdewalqu dans le forum Composants
    Réponses: 3
    Dernier message: 24/08/2006, 18h28
  2. Probleme [SWING]: JPanel dans JscrollPane
    Par malandro dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 24/05/2006, 22h02
  3. panel dans jscrollpane
    Par let_me_in dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 17/02/2006, 17h54
  4. [Swing] Désactiver roulette dans JScrollPane?
    Par Quintoff dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 14/01/2006, 19h39
  5. [Débutant] JPanel dans JScrollPane
    Par Nicolas_75 dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 06/04/2005, 10h39

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