Como adicionar uma imagem a um JPanel?

Eu tenho um JPanel ao qual eu'gostaria de adicionar imagens JPEG e PNG que eu gerei na mosca.

Todos os exemplos I'já vistos até agora em Swing Tutorials, especialmente em Swing examples utilizam ImageIcons.

I'm gerando estas imagens como matrizes de bytes, e geralmente são maiores que o ícone comum que usam nos exemplos, em 640x480.

  1. Existe algum (desempenho ou outro) problema na utilização da classe ImageIcon para exibir uma imagem daquele tamanho em um JPanel?
  2. Qual'é a forma usual de fazer isso?
  3. Como adicionar uma imagem a um JPanel sem usar a classe ImageIcon?

**Editar***: Um exame mais cuidadoso dos tutoriais e da API mostra que você não pode adicionar um ícone de imagem diretamente a um JPanel. Ao invés disso, eles conseguem o mesmo efeito definindo a imagem como um ícone de um JLabel. Isto simplesmente não'não parece certo...

Solução

Aqui's como o faço (com um pouco mais de informação sobre como carregar uma imagem):

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            
    }

}
Comentários (7)
  1. Não deve haver nenhum problema (além de qualquer problema geral que você possa ter com imagens muito grandes).
  2. Se você'está falando em adicionar múltiplas imagens em um único painel, eu utilizaria ImageIcons. Para uma única imagem, eu pensaria em fazer uma subclasse personalizada de JPanel e sobrepor seu método PintComponent para desenhar a imagem.
  3. (veja 2)
Comentários (0)

Você pode subclasse JPanel - aqui está um extrato do meu ImagePanel, que coloca uma imagem em qualquer um dos 5 locais, superior/esquerda, superior/direita, meio/interior, inferior/esquerda ou inferior/direita:

protected void paintComponent(Graphics gc) {
    super.paintComponent(gc);

    Dimension                           cs=getSize();                           // component size

    gc=gc.create();
    gc.clipRect(insets.left,insets.top,(cs.width-insets.left-insets.right),(cs.height-insets.top-insets.bottom));
    if(mmImage!=null) { gc.drawImage(mmImage,(((cs.width-mmSize.width)/2)       +mmHrzShift),(((cs.height-mmSize.height)/2)        +mmVrtShift),null); }
    if(tlImage!=null) { gc.drawImage(tlImage,(insets.left                       +tlHrzShift),(insets.top                           +tlVrtShift),null); }
    if(trImage!=null) { gc.drawImage(trImage,(cs.width-insets.right-trSize.width+trHrzShift),(insets.top                           +trVrtShift),null); }
    if(blImage!=null) { gc.drawImage(blImage,(insets.left                       +blHrzShift),(cs.height-insets.bottom-blSize.height+blVrtShift),null); }
    if(brImage!=null) { gc.drawImage(brImage,(cs.width-insets.right-brSize.width+brHrzShift),(cs.height-insets.bottom-brSize.height+brVrtShift),null); }
    }
Comentários (0)