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

Agents de placement/Fenêtres Java Discussion :

Problème d'affichage d'un JPanel dans un JFrame.


Sujet :

Agents de placement/Fenêtres Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur décisionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 10
    Points
    10
    Par défaut Problème d'affichage d'un JPanel dans un JFrame.
    Bonjour,
    Je code un jeu de cartes en Java.
    J'ai créée une JFrame. Je l'ai organisé avec un BorderLayout. J'ai créée un JPanel, que j'ai quadrillé avec un GridLayout.
    Pour un joueur donné, j'affiche les cartes de sa main dans le JPanel, en créeant un JLabel avec l'image de la carte correspondante, et en l'ajoutant au JPanel.
    Ensuite j'ajoute le JPanel au sud de la JFrame.


    Mon JPanel
    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
     
    import java.awt.*;
    import javax.swing.*;
     
     
    public class TestPanel extends JPanel{
     
    		Partie p;
     
    		public TestPanel(Partie p) {
    			this.p = p;
     
    		}
     
    		public void paintComponent(Graphics g)
    		   {
     
     
    		     this.setLayout(new GridLayout(1,p.getListeJoueurs().get(0).getMain().size()));
     
    		     for(Carte c : p.getListeJoueurs().get(0).getMain()){
    		    	 String titreImage;
                             //je cree le titre de mes images de cartes
    		    	 if(c.getNumber()<10){
    		    		 titreImage = "Images/Cartes/"+c.getSigne()+"_0"+c.getNumber()+".gif";
    		    	 }
    		    	 else{
    		    		 titreImage = "Images/Cartes/"+c.getSigne()+"_"+c.getNumber()+".gif";
    		    	 }
                             //je cree les composants porteur d'images
    		    	 JLabel carte = new JLabel(new ImageIcone(titreImage));
    		    	 System.out.println(titreImage);
    		    	 this.add(carte);
    		     }
     
     
    		   }
     
    	}

    Ma JFrame :

    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
     
    public class Fenetre extends JFrame {
     
     
     
    	public Fenetre(Partie p){
    		this.setTitle("Jeu");
    		this.setSize(1400, 650);
    		this.setLayout(new BorderLayout());
    		this.add("South",new TestPanel(p));
     
    		this.setLocationRelativeTo(null);               
    	        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    	}
     
     
    }
    La class principale de test

    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
     
     
    public class Go {
     
    	public static void main(String[] args) throws IOException {
                    //J'initialise ma partie.
    		Partie p = new Partie(3);
    		p.init();
                    // Je cree ma fenetre
    		Fenetre f = new Fenetre(p);
     
    	}
     
     
     
     
    }
    Je rencontre les problèmes suivants :
    1) La methode PaintComponent s'execute plusieurs fois d'affilée, je ne comprend pas pourquoi.
    2) La fenêtre s'affiche vide dans un premier temps, puis quand je clique sur le bouton d'agrandissement en haut à droite, mon JPanel apparait en bas de la page (mais avec trop de case, car ma methode paint component s'est executé plusieurs fois)
    Pourriez-vous m'aidez à resoudre ces problèmes ?
    De plus, je cherche a savoir comment:
    3)créer une grille avec un nombre de case fixe et des case à taille fixe (indépendante du nombre d'élément avec lequel je la remplis).
    4)Gérer la superposition de JPanel, par exemple, incoporer mon JPanel ci-dessus dans un JPanel qui aurait une image de fond, les images du premier s'affichant au dessus de celle du second.

    En espérant avoir été clair, je compte beaucoup sur votre aide et vous remercie d'avance.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    La méthode paintComponent() sert à rafraichir l'affichage du composant (exactement, c'est la méthode paint() qui sert à ça, et qui appellera, entre autre paintComponent()). Il ne faut pas construire le contenu du composant dans cette méthode, mais dans une autre méthode, par exemple dans le constructeur. Ainsi, les composants (les JLabel dans ton cas) seront ajoutés au panel, et bien redessiné au besoin lors de l'invocation de paint() (donc de paintComponent()), ce qui se fera soit quand SWING l'estimera nécessaire, soit quand tu auras besoin, auquel cas, il suffira d'appeller la méthode repaint() (par exemple, si tu ajoutes un nouveau composant dans le panel). A noter que dans ce dernier cas, si la modification implique un impact sur le layout (placement et taille), il faudra appeler revalidate() également.

    En plus, comme ajouter un composant à un conteneur force SWING à redessiner le conteneur, le fait de procéder comme tu le fais doit provoquer une boucle qui ajoute continuellement des cartes au panel...

    Donc, il suffit que ta classe soit donc comme ça :

    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
     
    import java.awt.*;
    import javax.swing.*;
     
     
    public class TestPanel extends JPanel{
     
    		Partie p;
     
    		public TestPanel(Partie p) {
    			this.p = p;
         	                this.setLayout(new GridLayout(1,p.getListeJoueurs().get(0).getMain().size()));
     
    		     for(Carte c : p.getListeJoueurs().get(0).getMain()){
    		    	 String titreImage;
                             //je cree le titre de mes images de cartes
    		    	 if(c.getNumber()<10){
    		    		 titreImage = "Images/Cartes/"+c.getSigne()+"_0"+c.getNumber()+".gif";
    		    	 }
    		    	 else{
    		    		 titreImage = "Images/Cartes/"+c.getSigne()+"_"+c.getNumber()+".gif";
    		    	 }
                             //je cree les composants porteur d'images
    		    	 JLabel carte = new JLabel(new ImageIcone(titreImage)); // ici, est-ce bien ImageIcone (et pas ImageIcon) ?
    		    	 System.out.println(titreImage);
    		    	 this.add(carte);
    		     }
     
    		}
     
    		/*public void paintComponent(Graphics g)
    		   {
     
     
     
     
    		   }*/
     
    	}
    S'il est nécessaire de reconstruire le contenu du composant en fonction de modifications dans l'état de la partie, il faudra faire une méthode spécique pour ajouter toutes les JLabel : avant de l'appeler une seconde fois, il faudra penser à supprimer les JLabel déjà ajoutés précédemment.

    Comme ça :

    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 TestPanel extends JPanel{
     
    		Partie p;
     
    		public TestPanel(Partie p) {
    			this.p = p;
     
    		}
     
                   public void construire() {
     
                         removeAll();// supprime tous les composants ajoutés précédemment
     
                         this.setLayout(new GridLayout(1,p.getListeJoueurs().get(0).getMain().size()));
     
    		     for(Carte c : p.getListeJoueurs().get(0).getMain()){
    		    	 String titreImage;
                             //je cree le titre de mes images de cartes
    		    	 if(c.getNumber()<10){
    		    		 titreImage = "Images/Cartes/"+c.getSigne()+"_0"+c.getNumber()+".gif";
    		    	 }
    		    	 else{
    		    		 titreImage = "Images/Cartes/"+c.getSigne()+"_"+c.getNumber()+".gif";
    		    	 }
                             //je cree les composants porteur d'images
    		    	 JLabel carte = new JLabel(new ImageIcone(titreImage)); // ici, est-ce bien ImageIcone (et pas ImageIcon) ?
    		    	 System.out.println(titreImage);
    		    	 this.add(carte);
    		     }
     
                         // demande le rafraichissement du layout et de l'affichage
                         revalidate();
                         repaint();
     
                   }
     
     
    	}
    A noter, que pour ajouter un composant avec contrainte, on utilise pas la méthode que tu utilises (qui est dépréciée, même s'il n'est pas notée dépréciée, elle l'est pas la doc). De plus, il vaut mieux utiliser les constantes fournies par BorderLayout.

    Donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.add(new TestPanel(p), BorderLayout.SOUTH);
    Pour ce qui est des autres questions :

    1) une grille de taille fixe
    Les paramètres du constructeur de GridLayout sont :
    1. le nombre de lignes
    2. le nombre de colonnes

    On ne peut fixer que l'un des deux (l'autre sera mis à 0, pour ne pas le fixer) : si tu fixes le nombre de lignes (nombre de lignes > 0), le nombre de colonnes sera déduit (par exemple ajouter 10 composants, sur 2 lignes donne 5 colonnes). Si tu fixes le nombre de colonnes (nombre de colonnes > 0), le nombre de lignes est déduit (s'il est à 0). Si tu fixes les deux, seul le paramètre de lignes sera pris en compte (c'est comme si tu ne fixais que le nombre de lignes).

    2) une grille avec des cases de tailles fixes
    On ne peut pas faire ça par la grille, avec un GridLayout (On pourrait le faire avec d'autres types de layout, comme le GridBagLayout, mais il est un peu plus complexe à utiliser) : la taille de ses cases s'adapte à la taille de la fenêtre dans laquelle elle s'affiche et à la taille des composants qui y sont mis. Pour avoir une grille avec des cases de taille fixe, il suffit d'y mettre des composants qui ont tous la même taille (par exemple des JLabel() avec des images qui ont toutes la même taille). Si le composant est plus complexe qu'une simple image, on peut utiliser pour chaque case un JPanel, dans lequel on met différents composants (textes, images, etc.) et forcer la taille des JPanel (en redéfinissant la méthode getPreferredSize()). Mais même comme ça, le JPanel s'étendra à la taille de la fenêtre. Pour l'empecher, on peut utiliser un GridBagLayout de 1x1 avec contrainte de base (cas simple d'utilisation du GridBagLayout), comme dans l'exemple suivant :

    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
    public class DemoPanel extends JPanel {
     
    	private final static Dimension TAILLE_CASE = new Dimension(32,32);
     
    	public DemoPanel() {
    		setLayout(new GridLayout(0,8));
    		boolean color=false;
    		for(int i=1; i<=64; i++) {
    			add( new Case(String.valueOf(i), color?Color.YELLOW:Color.WHITE));
    			if ( i%8!=0 ) {
    				color=!color;
    			}
    		}
    	}
     
    	public static class Case extends JPanel {
     
    		public Case(String texte, Color c) {
    			setBackground(c);
    			GridLayout layout = new GridLayout(1,0);
    			setLayout(layout);
    			add(new JLabel(texte, JLabel.CENTER));
    		}
     
    		@Override
    		public Dimension getPreferredSize() {
    			return TAILLE_CASE;
    		}
     
    	}
     
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("Démo");
     
     
    		JPanel centrage = new JPanel();
    		centrage.setLayout(new GridBagLayout()); 
    		centrage.add(new DemoPanel(), new GridBagConstraints());
     
    		frame.setContentPane(centrage);
     
    		frame.pack(); // dimensionne automatiquement la frame en fonction du contenu
     
    		frame.setLocationRelativeTo(null);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
     
    	}
     
    }
    3) Pour afficher une image de fond, par contre, on passe par la méthode paintComponent, en la redéfinissant. Mais ce n'est pas si simple que ça lorsqu'on utilise des composants dans des composants, car chaque composant SWING a une notion d'opacité. Un JLabel est transparent par défaut. Lorsqu'il s'agit de JPanel, il suffit de rendre le composant transparent en appelant setOpaque(false), mais pour d'autres composants, comme un JTextField ou un JComboBox, ce ne sera pas aussi simple.

    Par exemple (en mettant l'image, ici "suricate.jpg", dans le dossier qui contient le DemoPanel.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
    public class DemoPanel extends JPanel {
     
    	private final static Dimension TAILLE_CASE = new Dimension(32,32);
     
    	private final Image imageDeFond;
     
    	public DemoPanel() throws IOException {
    		this.imageDeFond=chargerImage();
    		setLayout(new GridLayout(0,8));
    		for(int i=1; i<=64; i++) {
    			add( new Case(String.valueOf(i)));
    		}
    	}
     
    	private Image chargerImage() throws IOException {
    		return ImageIO.read(getClass().getResource("suricate.jpg"));
    	}
     
    	@Override
    	public void paintComponent(Graphics g) {
    		g.drawImage( imageDeFond , 0, 0, getWidth(), getHeight(), this);
    	}
     
    	public static class Case extends JPanel {
     
    		public Case(String texte) {
    			setOpaque(false);
    			GridLayout layout = new GridLayout(1,0);
    			setLayout(layout);
    			add(new JLabel(texte, JLabel.CENTER));
    		}
     
    		@Override
    		public Dimension getPreferredSize() {
    			return TAILLE_CASE;
    		}
     
    	}
     
     
    	public static void main(String[] args) throws IOException {
     
    		JFrame frame = new JFrame("Démo");
     
    		JPanel centrage = new JPanel();
    		centrage.setLayout(new GridBagLayout()); 
    		centrage.add(new DemoPanel(), new GridBagConstraints());
     
    		frame.setContentPane(centrage);
     
    		frame.pack(); // dimensionne automatiquement la frame en fonction du contenu
     
    		frame.setLocationRelativeTo(null);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
     
    	}
     
    }

    Si on voulait combiner les deux, avec les cases en couleur, on pourrait utiliser la notion d'alpha, qui permet de contrôler la transparence d'une couleur.

    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
    public class DemoPanel extends JPanel {
     
    	private final static Dimension TAILLE_CASE = new Dimension(32,32);
     
    	private static final Color YELLOW_TRANSPARENT = new Color(255,255,0,128); // transparence 50%
    	private static final Color WHITE_TRANSPARENT = new Color(255,255,255,128); // transparence 50%
     
    	private final Image imageDeFond;
     
    	public DemoPanel() throws IOException {
    		this.imageDeFond=chargerImage();
    		setLayout(new GridLayout(0,8));
    		boolean color=false;
    		for(int i=1; i<=64; i++) {
    			add( new Case(String.valueOf(i), color?YELLOW_TRANSPARENT:WHITE_TRANSPARENT));
    			if ( i%8!=0 ) {
    				color=!color;
    			}
    		}
    	}
     
    	private Image chargerImage() throws IOException {
    		return ImageIO.read(getClass().getResource("suricate.jpg"));
    	}
     
    	@Override
    	public void paintComponent(Graphics g) {
    		g.drawImage( imageDeFond , 0, 0, getWidth(), getHeight(), this);
    	}
     
    	public static class Case extends JPanel {
     
    		public Case(String texte, Color color) {
    			setBackground(color);
    			GridLayout layout = new GridLayout(1,0);
    			setLayout(layout);
    			add(new JLabel(texte, JLabel.CENTER));
    		}
     
    		@Override
    		public Dimension getPreferredSize() {
    			return TAILLE_CASE;
    		}
     
    	}
     
     
    	public static void main(String[] args) throws IOException {
     
    		JFrame frame = new JFrame("Démo");
     
    		JPanel centrage = new JPanel();
    		centrage.setLayout(new GridBagLayout()); 
    		centrage.add(new DemoPanel(), new GridBagConstraints());
     
    		frame.setContentPane(centrage);
     
    		frame.pack(); // dimensionne automatiquement la frame en fonction du contenu
     
    		frame.setLocationRelativeTo(null);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
     
    	}
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur décisionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 10
    Points
    10
    Par défaut
    Merci pour toutes ces réponses et ces indications, cela m'est vraiment très utile.

    En ce qui concerne le GridLayout(0,8), cela veut dire que tu a fixé le nombre de colonnes à 8, je pense que cela vaudrait mieux pour mon JPanel en effet.

    A quel moment ta constante TAILLE_CASE entre-t-elle en jeu dans le GridBagLayout ?

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Patrick95500 Voir le message
    A quel moment ta constante TAILLE_CASE entre-t-elle en jeu dans le GridBagLayout ?
    Elle entre en jeu indirectement dans le GridBagLayout : elle est utilisée pour indiquer la taille (largeur et hauteur) préfentielle d'une case. Le GridLayout s'en sert pour déterminer la taille préférentielle des cases de sa grille, et par extension la taille préférentielle du composant qui est layouté par ce GridLayout, qui est, en l'occurance, 8×TAILLE_CASE (largeur et hauteur). Le paramétrage par défaut de la GridBagConstraint dans un GridBagLayout fait que la grille gérée (et donc le composant layouté par ce GridBagLayout) par le GridBagLayout prend la dimension préférentielle du composant qu'on y met, et se centre dans son propre conteneur. Si tu agrandis la fenêtre, ou si tu initialises une taille arbitraire plus grande que la taille 8×TAILLE_CASE au lieu de faire un pack() sur la JFrame, qui justement demande de déterminer automatiquement la taille préférentielle de son contenu, tu pourras le constater.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur décisionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 10
    Points
    10
    Par défaut
    Peut-on à la fois contrôler la taille du JPanel et la taille des cases de la grille?
    Si oui, Que se passerait-il si on a ajoute plus de cases qu'il n'y a de place dans le JPanel?

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Oui et non, et ça dépend des Layout Manager (de leur fonctionnement propre). Il faut l'éviter de manière générale : on peut imposer une taille préférentielle (ou maximum, ou minimum), pour les composants de base, mais il faut l'éviter pour les conteneurs et laisser faire le Layout Manager (ou en changer, si le résultat n'est pas satisfaisant), pour éviter les conflits et d'autres problèmes de gestion. De toute manière, tous les composants ajoutés à un conteneur y sont présents, quelque soit les dimensions, les Layout Manager, et les contraintes employés : plus on cherche à en combiner, plus on risque des conflits, ou des comportements incompréhensibles (surtout difficilement prévisibles). C'est pareil si tu force la taille d'une fenêtre à son minimum : on ne voit rien, mais les composants qui y ont été ajoutés y sont bien : simplement, on ne le voit pas.

    Par exemple, si on ajoutait à DemoPanel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    public Dimension getPreferredSize() {
       return new Dimension(128,128);
    }
    La taille préférentielle de l'échiquier (la grille de 8 par 8) serait simplement réduite pour avoir cette taille de 128 par 128 pixels. Le fait de rédéfinir la méthode getPreferredSize() ne fait que remplacer le comportement par défaut qui délègue la détermination de cette taille au Layout Manager.

    Si maintenant on faisait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    public Dimension getPreferredSize() {
         return new Dimension(32,32);
    }
    l'échiquier serait encore plus petit, mais on aurait une exception levée (Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!), pas du tout évidente à éviter : on entre dans le cadre des conflits que je décrivais ci-avant. Peu importe pourquoi et comment : il vaut mieux éviter de le faire, on s'évite des complications inutiles.

    Après, il y a une autre façon d'aborder la problématique d'afficher un composant trop grand (ou un groupe de composants) dans un conteneur plus petit : le JScrollPane. Ainsi, le contenu peut avoir sa propre taille, et le conteneur une autre taille, plus petite : le conteneur affichant des ascenseurs quand cela est nécessaire.

    On peut également procéder dans l'autre sens : avoir une taille fixe pour le conteneur et que les composants contenus s'adaptent pour tous s'afficher.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur décisionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 10
    Points
    10
    Par défaut
    Merci pour toutes ces Infos.
    J'ai suivi un très bon tuto pour le GridBagLayout que je conseille à ceux qui comme moi ont eu cette problématique:
    http://bbclone.developpez.com/fr/jav...gridbaglayout/

    Si je pouvais me permettre une autre question:
    Je cherche à afficher la main d'un joueur, et pour cela je voudrais que les cartes s'affichent en rangée les unes derrières les autres, en ne montrant qu'une moitié de la carte, sauf pour la dernière que l'on voit entièrement.
    comme sur cette image:
    http://img.clubic.com/012C0000000767...-3d-belote.jpg

    Dois-je créer pour chaque image une autre image qui serait sa moitié, ou dois-je créer un container plus petit ?
    Je ne vois pas de solution simple à cette problématique.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur décisionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 10
    Points
    10
    Par défaut
    Veuillez ne pas tenir de ma dernière question, j'ai réussi à trouver la solution grâce au JLayeredPane.
    Ce lien m'a beaucoup aidé :
    http://www.java2s.com/Code/Java/Swin...PaneSample.htm

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Pour être honnête, les layouts ne sont pas vraiment l'outil adapté pour ce que tu cherches à faire, de même que les composants swing par élément de ton jeu.
    Dès que tu vas vouloir faire la moindre animation, ça va être fout.


    Dans ce genre de cas, l'option à préconiser est plutôt de tout réaliser en dessinant à même un unique JComponent, dans sa méthode paintComponent.

    Plus de JLabel, plus de Layout, juste du Graphics2D.draw
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

Discussions similaires

  1. Affichage de différents JPanel dans une JFrame
    Par PROJECT-AURORA dans le forum Débuter
    Réponses: 13
    Dernier message: 16/11/2013, 11h22
  2. Ajout et affichage d'un JPanel dans une JFrame lorsqu'un évènement se produit
    Par bilou_12 dans le forum Agents de placement/Fenêtres
    Réponses: 0
    Dernier message: 27/03/2012, 20h27
  3. [SQL] Problème d'affichage de caractère spéciaux dans une variable chaîne
    Par Kryptonaute dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 18/08/2006, 08h40
  4. Problème d 'affichage d une grile dans un JLabel
    Par louby dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 26/06/2006, 15h56
  5. Problème de taille d'un JPanel dans un GridLayout
    Par ZamZam340 dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 30/04/2006, 20h56

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