371 votes

Comment ajouter une image à un JPanel ?

J'ai un JPanel à laquelle j'aimerais ajouter des images JPEG et PNG que je génère à la volée.

Tous les exemples que j'ai vus jusqu'à présent dans l'étude de la Tutoriels sur le Swing notamment dans les Exemples de balançoires utiliser ImageIcon s.

Je génère ces images sous forme de tableaux d'octets, et elles sont généralement plus grandes que l'icône commune utilisée dans les exemples, à savoir 640x480.

  1. Y a-t-il un problème (de performance ou autre) à utiliser la classe ImageIcon pour afficher une image de cette taille dans un JPanel ?
  2. Quel est le habituel manière de le faire ?
  3. Comment ajouter une image à un JPanel sans utiliser la classe ImageIcon ?

Editar : Un examen plus attentif des tutoriels et de l'API montre que vous ne pouvez pas ajouter une ImageIcon directement à un JPanel. Au lieu de cela, ils obtiennent le même effet en définissant l'image comme une icône d'un JLabel. Cela ne semble pas correct...

1 votes

En fonction de la manière dont vous générez les tableaux d'octets, il peut être plus efficace d'utiliser un fichier de type MemoryImageSource que de les convertir au format JPEG ou PNG et de les lire ensuite avec ImageIO comme le suggèrent la plupart des réponses. Vous pourriez obtenir un Image d'un MemoryImageSource construit avec vos données d'image en utilisant createImage et l'afficher comme suggéré dans l'une des réponses.

0 votes

551voto

Fred Haslam Points 4423

Si vous utilisez JPanels, vous travaillez probablement avec Swing. Essayez ceci :

BufferedImage myPicture = ImageIO.read(new File("path-to-file"));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
add(picLabel);

L'image est maintenant un composant swing. Elle devient soumise aux conditions de mise en page comme tout autre composant.

21 votes

Comment mettre l'image à l'échelle en fonction de la taille de la JLabel ?

2 votes

Beau code ! Je n'ai pas beaucoup d'expérience avec Swing mais je n'arrive pas à le faire fonctionner. Quelqu'un l'a-t-il essayé dans le jdk 1.6.0_16 ?

4 votes

@ATorras Je sais que vous avez posé cette question il y a un certain temps, mais si d'autres débutants ont eu les mêmes problèmes que moi, n'oubliez pas picLabel.setBounds() ;

267voto

bcash Points 3224

Voici comment je procède (avec un peu plus d'informations sur la façon de charger une image) :

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel{

    private BufferedImage image;

    public ImagePanel() {
       try {                
          image = ImageIO.read(new File("image name and path"));
       } catch (IOException ex) {
            // handle exception...
       }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, this); // see javadoc for more info on the parameters            
    }

}

0 votes

J'ai essayé de l'utiliser avec des boutons personnalisés en haut, et j'ai trouvé qu'il y avait des problèmes étranges de redessin. La réponse de Fred Haslam, ci-dessous, n'a pas souffert de ce problème.

20 votes

-1 pour une implémentation invalide de paintComponent (@Dogmatixed, c'est très probablement la raison pour laquelle vous avez ces problèmes de redécoupage) - il doit garantit de couvrir toute sa surface s'il déclare être opaque (ce qui est le cas par défaut), ce qui est plus facile à réaliser en appelant super.paintComponent

6 votes

@kleopatra, Merci, je n'avais pas réalisé cela... selon la javadoc : "De plus, si vous n'invoquez pas la mise en œuvre de super, vous devez honorer la propriété opaque, c'est-à-dire que si ce composant est opaque, vous devez remplir complètement l'arrière-plan dans une couleur non opaque. Si vous ne respectez pas la propriété opaque, vous verrez probablement des artefacts visuels." Je vais mettre à jour la réponse maintenant.

41voto

shawalli Points 132

La méthode de Fred Haslam fonctionne bien. J'ai cependant eu des problèmes avec le chemin d'accès au fichier, puisque je veux faire référence à une image dans mon jar. Pour ce faire, j'ai utilisé :

BufferedImage wPic = ImageIO.read(this.getClass().getResource("snow.png"));
JLabel wIcon = new JLabel(new ImageIcon(wPic));

Comme je n'ai qu'un nombre limité (environ 10) d'images à charger avec cette méthode, cela fonctionne très bien. Elle permet d'obtenir le fichier sans avoir besoin d'avoir le chemin de fichier relatif correct.

2 votes

J'ai remplacé la première ligne par BufferedImage previewImage = ImageIO.read(new URL(imageURL)); pour obtenir mes images à partir d'un serveur.

0 votes

Pour référencer des images à partir de jar, essayez ceci stackoverflow.com/a/44844922/3211801

33voto

CoderTim Points 191

Je pense qu'il n'est pas nécessaire de sous-classer quoi que ce soit. Utilisez simplement un Jlabel. Vous pouvez placer une image dans un Jlabel. Donc, redimensionnez le Jlabel puis remplissez-le avec une image. C'est bon. C'est la façon dont je fais.

19voto

Dan Vinton Points 11975

Vous pouvez éviter de développer votre propre sous-classe Component en utilisant la classe JXImagePanel de l'application gratuite SwingX bibliothèques.

Télécharger

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X