Como exibir imagem na tela utilizando Jframe e Graphics2d

Boa Noite pessoal, sou novo por aqui e esta é a minha primeira pergunta, que já foi perguntada mas não conseguiu resolver minha dúvida:

Quero exibir uma imagem na tela com Jframe usando a biblioteca graphics2d, utilizei o código do link a seguir https://www.guj.com.br/t/graphics2d/48864/14 e adaptei para a minha situação. O código ficou assim:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Desenhar extends JComponent {

private static final long serialVersionUID = 1L;
JFrame frame;
JPanel panel;

Desenhar() {
	frame = new JFrame("Tela");
	panel = new JPanel();
	panel.setLayout(null);
	frame.getContentPane().add(panel);
	frame.setVisible(true);
	frame.setSize(800, 600);
	panel.add(this);
	this.setBounds(50, 50, 100, 100);
}

public void paintComponent(Graphics g) {
	try {
		Graphics2D g2 = (Graphics2D) g;
		InputStream imgStream = getClass().getResourceAsStream("imagens/img.png");
		BufferedImage image = ImageIO.read(imgStream);
		g2.drawImage(image, 100, 100, panel);
		System.out.println("Imagem OK!");
	} catch (Exception e) {
		System.out.println("Imagem não localizada");
	}
}

public static void main(String[] args) {
	new Desenhar();
}

}

Acontece que a imagem não está sendo encontrada, criei uma pasta dentro do projeto com o nome de imagens e referenciei o caminho no código (“imagens/img.png”)

O que está havendo de errado?

Coloque uma barra na frente do imagens para procurar a partir da raíz do classpath de sua aplicação, assim:

InputStream imgStream = getClass().getResourceAsStream("/imagens/img.png");

Outra coisa, sua imagem é sempre a mesma, então instancie uma única vez, fora do método paintComponent, pois a responsabilidade desse método é somente pintar os gráficos e não carregar imagens.

1 curtida

Certo, o código ficou assim:

package auxiliares;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Desenhar extends JComponent {

private static final long serialVersionUID = 1L;
JFrame frame;
JPanel panel;

Desenhar() {
	frame = new JFrame("Tela");
	panel = new JPanel();
	panel.setLayout(null);
	frame.getContentPane().add(panel);
	frame.setVisible(true);
	frame.setSize(800, 600);
	panel.add(this);
	this.setBounds(50, 50, 100, 100);
}

//Imagem instanciada fora do metodo
InputStream imgStream = getClass().getResourceAsStream("/imagens/img.png");

public void paintComponent(Graphics g) {
	try {
		Graphics2D g2 = (Graphics2D) g;			
		BufferedImage image = ImageIO.read(imgStream);
		g2.drawImage(image, 100, 100, panel);
		System.out.println("Imagem OK!");
	} catch (Exception e) {
		System.out.println("Imagem não localizada");
	}
}

public static void main(String[] args) {
	new Desenhar();
}

}

Ainda continua saindo a janela sem nenhuma imagem, onde estou errando?

Aqui você não está instanciando a imagem.
Você continua instanciando a imagem no método paintComponent

Seu maior problema está no construtor, onde você cria um JFrame, cria um JPanel sem layout e adiciona o seu Desenhar nesse painel.

A responsabilidade do construtor é inicializar o Desenhar e não criar uma janela para apresentar.

Eu apagaria aquele construtor e faria o main assim:

public static void main(String[] args) {
    JFrame frame = new JFrame("Tela");
    frame.setSize(800, 600);
    Desenhar panel = new Desenhar();
    frame.add(BorderLayout.CENTER, panel);
    frame.setVisible(true);
}

Poderia me dizer exatamente como instanciar a variável? Se eu entendi corretamente modifiquei o código com sua sugestão ele ficaria igual abaixo?

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Desenhar extends JComponent {

private static final long serialVersionUID = 1L;
JFrame frame;
JPanel panel;

//Instanciar a imagem fora do metodo
InputStream imgStream = getClass().getResourceAsStream("/imagens/img.png");
BufferedImage image = ImageIO.read(imgStream);

public void paintComponent(Graphics g) {
	try {
		Graphics2D g2 = (Graphics2D) g;					
		g2.drawImage(image, 100, 100, panel);
		System.out.println("Imagem OK!");
	} catch (Exception e) {
		System.out.println("Imagem não localizada");
	}
}

public static void main(String[] args) {
	   JFrame frame = new JFrame("Tela");
	    frame.setSize(800, 600);
	    Desenhar panel = new Desenhar();
	    frame.add(BorderLayout.CENTER, panel);
	    frame.setVisible(true);
}

}

Mas acusa erro de compilação na linha de BufferedImage image = ImageIO.read(imgStream);

Desculpe a minha ignorância, se eu tivesse um exemplo pronto que funcionasse eu conseguiria me virar aqui, mas não estou conseguindo entender o básico.

Que erro?

Olha o print do programa

https://ap.imagensbrasil.org/image/rOc4o6

É que o ImageIO.read pode lançar exceção.
Inicializa a variável no construtor, dentro de um try-catch.

Recriei o construtor, o programa roda e a mensagem “Imagem OK!” aparece, mas a imagem não aparece:

package auxiliares;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Desenhar extends JComponent {

private static final long serialVersionUID = 1L;
JFrame frame;
JPanel panel;
BufferedImage image;

public Desenhar() {
	try {
		image = ImageIO.read(imgStream);
	} catch (Exception e) {

	}
}

InputStream imgStream = getClass().getResourceAsStream("/imagens/img.png");

public void paintComponent(Graphics g) {
	try {
		Graphics2D g2 = (Graphics2D) g;
		g2.drawImage(image, 100, 100, panel);
		System.out.println("Imagem OK!");
	} catch (Exception e) {
		System.out.println("Imagem não localizada");
	}
}

public static void main(String[] args) {
	JFrame frame = new JFrame("Tela");
	frame.setSize(800, 600);
	Desenhar panel = new Desenhar();
	frame.add(BorderLayout.CENTER, panel);
	frame.setVisible(true);
}

}

Aqui o seu código funcionou perfeitamente.
Tem certeza de que a pasta imagens está no classpath de sua aplicação?

Se quiser simplificar um pouco seu programa:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Desenhar extends JComponent {

    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        JFrame frame = new JFrame("Tela");
        frame.setSize(800, 600);
        Desenhar panel = new Desenhar();
        frame.add(BorderLayout.CENTER, panel);
        frame.setVisible(true);
    }

    private BufferedImage image;

    public Desenhar() {
        try {
            InputStream imgStream = getClass().getResourceAsStream("/imagens/img.png");
            image = ImageIO.read(imgStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 100, 100, this);
    }
}
1 curtida

Agora sim! Rapaz muito obrigado. Acontece que o método não estava encontrando a imagem. Então eu criei um pacote dentro da pasta src com o nome imagem e coloquei a imagem lá dentro, ai funcionou corretamente. Valeu mesmo pela ajuda, o erro estava nos detalhes!

1 curtida