Tableau d'imagesen JAVA

[Résolu/Fermé]
Signaler
Messages postés
7
Date d'inscription
dimanche 31 mai 2015
Statut
Membre
Dernière intervention
3 juin 2015
-
Messages postés
7
Date d'inscription
dimanche 31 mai 2015
Statut
Membre
Dernière intervention
3 juin 2015
-
Bonjour ! Je post afin de m'en remettre à vous car je n'arrive pas à parcourir un tableau et afficher les images situées dans un autre tableau en fonction de ce qui est lu dans le premier..

Peut-être est ce la fatigue mais je ne vois pas ou est mon erreur ? Pourriez vous m'aider s'il vous plait ?

Voici le dit-code :
public static void draw(int[][] level, BufferedImage[] spriteSheet){

int readLevel = 0, readSprite = 0, q = 0;
int x = 0, y = 0;
JPanel levelPanel = new JPanel();
JLabel [] levelLabel = new JLabel [500];
Image [] tileLevel = new Image [500];
ImageIcon [] iconLevel = new ImageIcon [500];

levelPanel.setLayout(null);



for(int i = 0; i < 25; i++){
for(int j = 0; j < 20;j++){

readLevel = level[i][j];

switch(readLevel){

case 0:
readSprite = 0;
break;
case 1:
readSprite = 1;
break;
default:
break;
}

tileLevel [q] = Toolkit.getDefaultToolkit().createImage(spriteSheet[readSprite].getSource());
iconLevel [q] = new ImageIcon(tileLevel[q]);
levelLabel[q].setIcon(iconLevel[q]);
levelLabel[q].setBounds(x,y,32,32);
levelPanel.add(levelLabel[q]);
q++;

if( x <= 768){
x += 32;
}
else{

x = 0;
y += 32;
}

}
}

window.getMainFrame().setContentPane(levelPanel);
window.getMainFrame().validate();

}


Merci d'avance !

2 réponses

Messages postés
16374
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
5 août 2021
2 861
Bonjour,

Déjà il faut éviter les méthodes qui font tout, il vaut mieux les diviser.
Là tu as à la fois du traitement de données, de l'affichage... ça ne devrait pas être au même endroit.

De plus, il y a des "valeurs magiques" (ex: new JLabel[500], pourquoi 500 ?), là encore c'est à éviter. Il faut préférer passer ces valeurs en paramètres, ou les enregistrer dans des constantes, voire les recalculer.
Par exemple, 500, c'est 25*20, les dimensions de level[i][j], donc autant récupérer ces valeurs directement depuis level.

Ensuite, ton switch(readLevel) est maladroit, si readLevel[i][j] ne peut contenir que 0 ou 1, alors autant faire un boolean[][] plutôt qu'un int[][].
S'il peut y avoir d'autres valeurs, alors tu as un problème avec ton default qui ne définit pas de valeur pour readSprite.

Pour ce code
tileLevel [q] = Toolkit.getDefaultToolkit().createImage(spriteSheet[readSprite].getSource());
Notons déjà que la manière dont q est incrémenté est maladroite, le q++ est caché au milieu du code, il devrait être plus visible, par exemple au niveau du for. Ensuite tu fais 500 createImage alors que readSprite ne peut prendre que deux valeurs (0 ou 1), tu ferais mieux de ne créer que 2 fois ces valeurs. Même si en réalité c'est inutile puisque BufferedImage est déjà une Image donc tu peux l'utiliser tel quel sans avoir à passer par le Toolkit.

levelLabel[q].setBounds(x,y,32,32);

if( x <= 768){
 x += 32;
}
else{
 x = 0;
 y += 32;
}

Là il y a un problème, tu devrais te servir d'un GridLayout plutôt que de faire
levelPanel.setLayout(null);
ça simplifiera grandement les choses...

Enfin, tu n'as pas besoin de tous tes tableaux levelLabel, tileLevel, IconLevel, la seule chose qui t'intéresse c'est le level Panel final... du coup ça règle aussi le problème d'incrémentation de q.

Ce code devrait normalement faire plus ou moins la même chose :

public static void draw(int[][] level, BufferedImage[] spriteSheet) {

    JPanel levelPanel = buildLevelPanel(level, spriteSheet);

    window.getMainFrame().setContentPane(levelPanel);
    window.getMainFrame().validate();
}

public static JPanel buildLevelPanel(int[][] level, BufferedImage[] spriteSheet) {

    int rows = level.length;
    int cols = level[0].length;

    JPanel levelPanel = new JPanel(new GridLayout(rows, cols));

    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            int readSprite = level[row][col];
            Image tileLevel = spriteSheet[readSprite];
            ImageIcon iconLevel = new ImageIcon(tileLevel);
            JLabel levelLabel = new JLabel(iconLevel);
            levelPanel.add(levelLabel);
        }
    }

    return levelPanel;
}

La confiance n'exclut pas le contrôle
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
7
Date d'inscription
dimanche 31 mai 2015
Statut
Membre
Dernière intervention
3 juin 2015

Merci de ta réponse mais en la lisant il y a quelque chose qui m'échappe. Dans ta double boucle for tu construis un JLabel en lui passant une IconImage en paramètre puis tu ajoute ton Label au panel. Mais comme ta boucle s'exécute X fois tu changes juste l'image du Label, tu ne créée pas X label ? et au final ton panel n'a qu'un seul Label avec une image ?
Messages postés
16374
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
5 août 2021
2 861
"Mais comme ta boucle s'exécute X fois tu changes juste l'image du Label, tu ne créée pas X label ? et au final ton panel n'a qu'un seul Label avec une image ?"

Non. Le JLabel est créé à l'intérieur de la boucle, il est donc unique pour chaque tour de boucle. Une fois qu'on a fait
levelPanel.add(levelLabel)
on a plus besoin de travailler sur ce JLabel, il n'est alors géré que par le levelPanel, c'est suffisant.

C'est pour ça que tes tableaux (JLabel[] levelLabel par exemple) sont inutiles, tu stockes des valeurs pour rien puisqu'une fois la méthode draw terminée le tableau disparaît de toute façon...
Messages postés
7
Date d'inscription
dimanche 31 mai 2015
Statut
Membre
Dernière intervention
3 juin 2015

Ah d'accord ! Ceci les tutos et cours sur le net ne l'on jamais mentionné ! Je vais donc me pencher sérieusement sur ta solution !
Messages postés
7
Date d'inscription
dimanche 31 mai 2015
Statut
Membre
Dernière intervention
3 juin 2015

Est ce que lorsque l'on créer une fenêtre via JFrame la taille que l'on rentre ( 800*600 par exemple) inclue la fenêtre de son bord haut gauche extérieur ou du bord intérieur de la fenêtre ?
Messages postés
16374
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
5 août 2021
2 861
Ca dépend comment est définie cette dimension.

Si tu fais :

JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.setVisible(true);

La taille 800, 600 est définie par rapport à la JFrame, c'est donc tout inclus (avec la barre de titre, les boutons fermer, réduire, ainsi que les bords sur les côtés).

Si tu fais :

JFrame frame = new JFrame();
frame.getContentPane().setPreferredSize(new Dimension(800 ,600));
frame.pack();
frame.setVisible(true);

La taille 800, 600 est définie par rapport au contenu de la JFrame, la taille réelle de la fenêtre sera donc plus grande, mais le contenu sera bien de la taille voulue.
Messages postés
7
Date d'inscription
dimanche 31 mai 2015
Statut
Membre
Dernière intervention
3 juin 2015

D'accord et bien merci à toi j'ai toutes mes réponses !