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

 Java Discussion :

Fonctionnement de la méthode pack()


Sujet :

Java

  1. #1
    Membre averti
    Inscrit en
    Août 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 13
    Par défaut Fonctionnement de la méthode pack()
    Hello,

    Une petite question.

    Dans un JPanel j'ai mis 10 JLabel contenant chacun une ImageIcon.

    L'affichage permet d'afficher 8 JLabel par ligne, donc 2 sur la ligne ci-dessous.

    Mon problème est que lorsque j'utilise la méthode Pack() , celle-ci ne s'applique qu'a la premiere ligne et non pas aux deux.

    Je ne comprends pas vraiment comment fonctionne cette méthode.

    Pourquoi s'ajuste-t-elle uniquement à la première ligne d'images et ne prends pas en compte la deuxième ligne, composée de 2 JLabel seulement ?

    Voila le code (je fais quelques tests de méthodes pour voir le rendu

    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
    package entrainement;
     
    import java.awt.Container;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;
     
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
     
    public class Fenetre extends JFrame implements MouseMotionListener
    {
    	private JPanel panneau ;
    	private JLabel bouton1, bouton2, bouton3, bouton4, bouton5, bouton6, bouton7, bouton8, bouton9, bouton10 ;
     
    	public Fenetre()
    	{
    		setTitle("Ma Fenêtre") ;
     
    		//On définit un panneau qui va devenir notre contentPane
    		panneau = new JPanel() ;
    		Container contenu = getContentPane() ;
    		contenu.add(panneau) ;
     
    		//Creation des boutons
    		bouton1 = new JLabel(new ImageIcon("aide_dragon.jpg")) ;
    		bouton2 = new JLabel(new ImageIcon("aide_fish.jpg")) ;
    		bouton3 = new JLabel(new ImageIcon("aide_goliath.jpg")) ;
    		bouton4 = new JLabel(new ImageIcon("aide_snail.jpg")) ;
    		bouton5 = new JLabel(new ImageIcon("aide_squid.jpg")) ;
    		bouton6= new JLabel(new ImageIcon("aide_turtle.jpg")) ;
    		bouton7 = new JLabel(new ImageIcon("aide_goliath.jpg")) ;
    		bouton8 = new JLabel(new ImageIcon("aide_snail.jpg")) ;
    		bouton9 = new JLabel(new ImageIcon("aide_squid.jpg")) ;
    		bouton10 = new JLabel(new ImageIcon("aide_turtle.jpg")) ;
     
    		//Ajout des boutons au panel
    		panneau.add(bouton1) ;
    		panneau.add(bouton2) ;
    		panneau.add(bouton3) ;
    		panneau.add(bouton4) ;
    		panneau.add(bouton5) ;
    		panneau.add(bouton6) ;
    		panneau.add(bouton7) ;
    		panneau.add(bouton8) ;
    		panneau.add(bouton9) ;
    		panneau.add(bouton10) ;
     
     
    		//Ecouteurs
    		bouton1.addMouseMotionListener(this) ;
    		bouton2.addMouseMotionListener(this) ;
    		bouton3.addMouseMotionListener(this) ;
    		bouton4.addMouseMotionListener(this) ;
    		bouton5.addMouseMotionListener(this) ;
    		bouton6.addMouseMotionListener(this) ;
    		bouton7.addMouseMotionListener(this) ;
    		bouton8.addMouseMotionListener(this) ;
    		bouton9.addMouseMotionListener(this) ;
    		bouton10.addMouseMotionListener(this) ;
    	}
     
    	@Override
    	public void mouseDragged(MouseEvent e)
    	{
    		JLabel temp=(JLabel)e.getSource();
     
    		temp.setBounds(temp.getX()+e.getX()-80,temp.getY()+e.getY()-60,160,120);
    	}
     
    	public static void main(String[] args)
    	{
    		Fenetre test = new Fenetre() ;
    		test.pack() ;
    		test.setVisible(true) ;
    	}
    	@Override
    	public void mouseMoved(MouseEvent e)
    	{
    		// TODO Auto-generated method stub
     
    	}
     
     
     
    }



    Et les screens :

    - Voici le résultat qui s'affiche sur mon écran

    http://img200.imageshack.us/img200/3508/imag1g.png

    (Dsl pour le PNG, j'ai oublié de les convertir JPG)


    - Et Voici ce que je voudrais voir affiché

    http://img193.imageshack.us/img193/7999/image2zhq.png


    De ce que j'avais compris, la méthode pack()permet d'ajuster la taille en fonction des composantes.

    Comment se fait-il donc qu'il s'ajuste bien en fonction de mes 8 premières images, mais pas en fonction des 2 supplémentaires ?

  2. #2
    Membre averti
    Inscrit en
    Août 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 13
    Par défaut
    Hello,

    Des lectures que j'ai pu faire sur le peu d'infos trouvées concernant pack(), il semble que pack récupère les setPreferredSize() des composantes.

    Est-ce que le compilo pense que j'affiche 10 images comme si c'était sur "une seule" ligne ? Ainsi il considérerait que la hauteur d'affichage serait seulement la hauteur d'une image ? car là la largeur il me met 8 de mes images, mais en hauteur il ne met que la taille d'une seule image.

    Je n'arrive pas à comprendre pourquoi il n'affiche pas la 2ème ligne d'images...

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    est-ce que la fenetre ferait, par hasard, toute la largeur de l'écran?
    Aussi pourrais tu remplacer ton main par ce code?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public static void main(String[] args)
    	{
                 SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
    		  Fenetre test = new Fenetre() ;
    		  test.setVisible(true) ;
    		  test.pack() ;
                 });
    	}
    En effet, le pack() doit normalement etre appelé après que la fenetre soit rendue visible et ls opérations sur les composant swing ne peuvent se faire qu'au sein de l'EDT!

  4. #4
    Membre averti
    Inscrit en
    Août 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 13
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    est-ce que la fenetre ferait, par hasard, toute la largeur de l'écran?
    Aussi pourrais tu remplacer ton main par ce code?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public static void main(String[] args)
    	{
                 SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
    		  Fenetre test = new Fenetre() ;
    		  test.setVisible(true) ;
    		  test.pack() ;
                 });
    	}
    En effet, le pack() doit normalement etre appelé après que la fenetre soit rendue visible et ls opérations sur les composant swing ne peuvent se faire qu'au sein de l'EDT!
    Hello Modo !

    Merci pour cette réponse, et désolé pour mon retard j'avais un problème de connexion.

    Alors d'abord, n'y aurait-il pas un problème dans ton bout de code ? Genre... Une accolade?

    J'ai corrigé comme cela, est-ce correct ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static void main(String[] args)
    	{
                 SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
    		  Fenetre test = new Fenetre() ;
    		  test.setVisible(true) ;
    		  test.pack() ;
                 }});
    	}

    Ensuite deux petites chose :

    - Qu'est ce que l'EDT ? (Je suis Novice)
    - Je n'ai pas très bien compris ta manip, pourrais-tu stp l'expliquer en quelques mots ?

    Par contre cela ne fonctionne pas... J'avoue sécher.

    Personne n'a une petite idée :$ ?

  5. #5
    Membre chevronné Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    457
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Novembre 2003
    Messages : 457
    Par défaut
    Citation Envoyé par shadowolf Voir le message
    Ensuite deux petites chose :

    - Qu'est ce que l'EDT ? (Je suis Novice)
    - Je n'ai pas très bien compris ta manip, pourrais-tu stp l'expliquer en quelques mots ?
    Pour plus d'information sur EDT, voici un excellent article de Romain Guy Threads et Performance avec Swing.
    Pour la manip de tchize_:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          Fenetre test = new Fenetre();
          test.setVisible(true);
          test.pack();
        }
      });
    }
    Il s'agit de créer la fenêtre dans l'EDT (voir l'article), ça évite que l'application semble figer lorsque tu mets à jour un composant graphique, où lorsque tu effectues un traitement long.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par shadowolf Voir le message
    J'ai corrigé comme cela, est-ce correct ?
    Oui, oublié de fermer le run
    - Qu'est ce que l'EDT ? (Je suis Novice)
    - Je n'ai pas très bien compris ta manip, pourrais-tu stp l'expliquer en quelques mots ?
    Merci de consulter les FAQs à ce sujet. Tout y est clairement expliqué.

    Par contre cela ne fonctionne pas... J'avoue sécher.
    J'avoue m'être renseigné. Le "preferredSize" d'un flowlayout vaut {largeur=somme(largeur des composant), hauteur=maximum(hauteur des composant)}. quand ont lui demande sa taille préférée, il repond donc comme si tout tenait dans une seul ligne. Hors pack utilise la taille préférée du composant. A cela se rajoute ton OS qui va interdire une largeur de fenetre plus large que ton desktop, et tu fini avec des données tronquées. Une solution suggérée chez sun, c'est d'étendre flowlayout pour faire toi même ton calcul de preferredsize sur base de tes propres critères (exemple: maximum 10 composants par ligne ou maximum 800 pixels par ligne)

  7. #7
    Membre chevronné Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    457
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Novembre 2003
    Messages : 457
    Par défaut
    Je viens de regarder les screens.
    En fait ton problème vient de :
    Par défaut ce constructeur va utiliser le FlowLayout qui lui préfère travailler sur une seule ligne.
    Donc quand tu fais un pack(). La fenêtre va s'agrandir et l'affichage se fera sur une seule ligne.

  8. #8
    Membre averti
    Inscrit en
    Août 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 13
    Par défaut
    Bonjour,

    Désolé pour ce retard une seconde fois... J'ai de gros problèmes de connexion internet ces temps ci.

    Merci beaucoup Tchize_ pour cette réponse. J'ai relu l'article, et commencé à essayer d'étendre le flowLayout.

    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
    package entrainement;
     
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
     
    public class ButtonLayout extends FlowLayout
    {
     
    	@Override
    	public Dimension preferredLayoutSize(Container target)
    	{		
    		int hauteur = super.preferredLayoutSize(target).height * 2 ;
     
    		System.out.println(hauteur) ;
     
    		super.preferredLayoutSize(target).setSize(super.preferredLayoutSize(target).width, hauteur) ;
     
    		return super.preferredLayoutSize(target);
    	}
     
    }
    La taille est bien doublée mais pourtant il refuse de me remettre la bonne taille dans mon laYout.

    Une idée ?

  9. #9
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    preferedlayoutsize est une méthode qui fait le calcul à chaque fois. Inutile d'essayer d'y stocker quoi que ce soit. Utilise plutot ce genre de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public Dimension preferredLayoutSize(Container target)
    	{		
                   Dimension d = super.preferredLayoutSize(target)
    	       d.height=d.height*2;
    	       return d;
    	}

  10. #10
    Membre averti
    Inscrit en
    Août 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 13
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    preferedlayoutsize est une méthode qui fait le calcul à chaque fois. Inutile d'essayer d'y stocker quoi que ce soit. Utilise plutot ce genre de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public Dimension preferredLayoutSize(Container target)
    	{		
                   Dimension d = super.preferredLayoutSize(target)
    	       d.height=d.height*2;
    	       return d;
    	}
    Alleluïa je te bénis...

    Pffff et moi qui pensait au départ que c'était un truc tout con...

    Un grand merci pour votre aide !!!

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 25/03/2008, 11h31
  2. Fonctionnement de la méthode DragMode
    Par soso78 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 24/03/2007, 00h17
  3. Fonctionnement de la méthode Compiler
    Par Cyberbob002 dans le forum 4D
    Réponses: 6
    Dernier message: 21/11/2006, 18h38
  4. fonctionnent de la méthode run dans les threads
    Par L4BiN dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 25/07/2006, 11h06
  5. Problème avec la méthode pack()
    Par tomca dans le forum Langage
    Réponses: 5
    Dernier message: 15/09/2005, 10h58

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