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

AWT/Swing Java Discussion :

PreferredSize en fonction du contenu et non du contenant


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 93
    Par défaut PreferredSize en fonction du contenu et non du contenant
    Bonjour à tous,

    Dans un JScrollPane, je souhaite afficher une série de bandeaux horizontaux (JPanels comprenant divers éléments), ajoutés par programmation et dont je ne connais pas à l'avance le nombre.

    Ils occupent toute la largeur du ScrollPane.
    Et leur hauteur DOIT varier en fonction de leur contenu.
    Il peut donc très bien rester une partie vide sous la liste, tout comme au contraire exiger l'activation et l'utilisation de l'ascenseur.

    Pour l'instant, j'utilise un BoxLayout en Y_AXIS.
    En largeur, ça va.

    Par contre, en hauteur, c'est la cata : il ajuste la hauteur des bandeaux en fonction de la hauteur du JScrollPane, ce qui revient soit à les distendre exagérément, soit au contraire à les couper en partie.

    Pire encore : la hauteur des éléments qui se trouvent dans le bandeau sont eux-mêmes ajustés à la hauteur du bandeau. Résultat : des textArea quasi vide, et des comboBox mahouse, c'est franchement pas beau.

    Comment faire pour ajuster la hauteur d'un composant en fonction de la hauteur préférée de son contenu, et non de son contenant ?
    J'ai tout essayé, et j'ai vu des trucs comme setPreferredSize(getPreferredSize()), mais sans succès.

    Merci de votre aide,

    P.S. : Pour ceux qui connaissent, je souhaite reproduire la "ZoneRépétée" que l'on trouve dans Windev/Webdev.

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 155
    Par défaut
    Moi je n'arrive pas a reproduire ton comportement.

    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
     
    public class TestScroll {
    	public static void main(String[] args) {
    		JFrame jf = new JFrame();
    		jf.setSize(400, 200);
     
    		JPanel jp = new JPanel();
    		jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
     
    		JComponent lblTemp = new JButton("lol");
    		lblTemp.setBackground(Color.MAGENTA);
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
    		lblTemp = new JLabel("ca marche pourtant");
    		jp.add(lblTemp);
     
    		JScrollPane jsp = new JScrollPane(jp);
     
    		jf.setBackground(Color.RED);
    		jsp.setBackground(Color.GREEN);
    		jp.setBackground(Color.CYAN);
     
    		jf.add(jsp);
    		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		jf.setVisible(true);
    	}
    }
    Un exemple?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 93
    Par défaut
    Oui.

    Je reviens sur ce sujet laissé de côté, et qui continue à m'en...quiquiner.

    J'ai reproduit le comportement par ces deux classes développées "rapido" sous NetBeans.

    @Merill : La différence avec ton exemple, c'est qu'il s'agit d'une liste de panels (ici, "Box").

    Résultat : ils s'allongent avec le cadre (ici, "LayoutTestForm"). Qu'ils s'adaptent en largeur me convient. Mais en hauteur, je veux que les "cellules" ("Box") conservent la prefSize du contenu.

    J'imagine qu'il me faut ajouter un espace "vide" en-dessous, mais ça m'ennuierait de devoir recalculer à chaque fois les dimensions du contenant pour renseigner Box.Filler(). Y a-t-il une autre option ?

    Merci pour toute suggestion,

    Classe LayoutTestForm.java
    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
    package layouttest;
     
    public class LayoutTestForm extends javax.swing.JFrame {
     
        public LayoutTestForm() {
            initComponents();
            setStrips();
        }
     
        private void setStrips() {
            String[] labels = {"Test 1",
            "test 2",
            "Test 3",
            "Test 4"};
     
            for(String s : labels) {
                Box box =  new Box(s);
                jPanel1.add(box);
            }        
        }
        @SuppressWarnings("unchecked")
        private void initComponents() {
     
            jScrollPane1 = new javax.swing.JScrollPane();
            jPanel1 = new javax.swing.JPanel();
     
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
     
            jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS));
            jScrollPane1.setViewportView(jPanel1);
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE)
                    .addContainerGap())
            );
     
            pack();
        }
     
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new LayoutTestForm().setVisible(true);
                }
            });
        }
     
        private javax.swing.JPanel jPanel1;
        private javax.swing.JScrollPane jScrollPane1;
     
    }
    Classe "Box.java"
    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
    package layouttest;
     
    public class Box extends javax.swing.JPanel {
     
        public Box() {
            initComponents();
        }
     
        public Box(String label) {
            this();
            this.jLabel1.setText(label);
        }
     
        @SuppressWarnings("unchecked")
        private void initComponents() {
     
            jLabel1 = new javax.swing.JLabel();
     
            jLabel1.setText("jLabel1");
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
            this.setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE)
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addContainerGap(17, Short.MAX_VALUE)
                    .addComponent(jLabel1)
                    .addContainerGap())
            );
        }
        private javax.swing.JLabel jLabel1;
     
    }

  4. #4
    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
    Bof bof pour les choix de layouts.

    Avec un GridBagLayout c'est quand même hypra simple à faire:


    Exemple

    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
     
    package swing.layout;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.util.ArrayList;
    import java.util.List;
     
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
     
    public class GridBagTestForm extends JPanel {
     
        private List<JPanel> panels;
        private Color[] borderColors = { Color.blue, Color.yellow, Color.green, Color.red, Color.black, Color.orange };
        private int[] panelHeights = { 10, 45, 20, 35, 60, 15, 30 };
     
        public GridBagTestForm() {
            panels = new ArrayList<JPanel>();
            init();
        }
     
        private GridBagConstraints createConstraints() {
            GridBagConstraints c = new GridBagConstraints();
            c.gridx = 0;
            c.gridy = GridBagConstraints.RELATIVE;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.weightx = 1.0f;
            c.anchor = GridBagConstraints.NORTH;
     
            return c;
        }
     
        private GridBagConstraints createFillConstraints() {
            GridBagConstraints c = new GridBagConstraints();
            c.gridx = 0;
            c.gridy = GridBagConstraints.RELATIVE;
            c.fill = GridBagConstraints.BOTH;
            c.weightx = 1.0f;
            c.weighty = 1.0f;
            c.anchor = GridBagConstraints.NORTH;
     
            return c;
        }
     
        private void init() {
            this.setLayout(new GridBagLayout());
            this.setBackground(Color.CYAN);
            GridBagConstraints c = createConstraints();
            for (int i = 0; i < 40; i++) {
                JPanel p = new JPanel();
                p.setBackground(borderColors[i % borderColors.length]);
                p.setPreferredSize(new Dimension(0, panelHeights[i % panelHeights.length]));
     
                this.add(p, c);
            }
            JPanel filler = new JPanel();
            filler.setOpaque(false);
            filler.setPreferredSize(new Dimension(0,0));
            filler.setMinimumSize(new Dimension(0,0));
            this.add(filler, createFillConstraints());
        }
     
        public static void main(String[] args) {
            GridBagTestForm gbtf = new GridBagTestForm();
            JFrame f = new JFrame();
            f.add(new JScrollPane(gbtf));
            f.pack();
            f.setLocationRelativeTo(null);
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setVisible(true);
        }
     
    }

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 93
    Par défaut


    Je ne connais pas ce Layout, mais à première vue, il ne me semble pas "hypra simple", en tout cas par comparaison au BoxLayout.

    Par ailleurs, je vois que tu as fixé des hauteurs arbitraires a priori. De mon côté, je ne les connais pas. Est-ce que ça va le faire ?

    J'essaie. Merci pour ta réponse.

  6. #6
    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
    Les hauteurs arbitraires étaient juste là pour l'exemple. De fait chaque composant calcule lui même sa preferredSize en fonction de son contenu, puis le gridBagLayout s'adapte automatiquement.

    Le tuto officiel sur le GridBagLayout. Qui est effectivement plus complexe que les Layouts standards, mais au combien plus flexible.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/09/2006, 00h47
  2. [CSS]auto agrandire un iframe en fonction du contenu
    Par hansaplast dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 09/08/2006, 12h36
  3. [VBA]comptage de lignes en fonction du contenu des cellules
    Par calimero91 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 22/12/2005, 11h38
  4. [DOM] Lecture de XML et décision en fonction du contenu
    Par samios dans le forum Format d'échange (XML, JSON...)
    Réponses: 6
    Dernier message: 14/10/2004, 16h09
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39

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