Imagem

galera o q eu errei aqui por q meu retângulo não aparece, nossa eu vou surtar com esse negocio de inserir imagem.

public class Principal {
	private static final long serialVersionUID = 1L;

	public JFrame frame = new JFrame();
	Componentes c = new Componentes();

	public Principal() {

		frame.setSize(400, 400);
		frame.setTitle("Elaine");
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(null);

		frame.add(c);
		c.startImage();
		
		frame.setVisible(true);

	}

	public static void main(String[] args) {

		Principal p = new Principal();

	}

}

////////////////////////////
public class Componentes extends JPanel {

	ImageIcon imagem = new ImageIcon(getClass().getResource("imagem.jpg"));
	BufferedImage buffered;
	public Graphics2D g2;

	

	public  Componentes() {
		
		buffered = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
		g2 = (Graphics2D) buffered.getGraphics();
		
	
	}
  
	public void startImage() {
		render1();
		
	}
	
	
	
	public void render1() {
		g2.setColor(Color.BLUE);
		g2.fillRect(20, 20, 50, 50);
		

	}

	public void paintComponent(Graphics2D g) {
g.drawImage(buffered, 0, 0, null);
	}

}

Em nenhum momento a variavel buffered está recebendo uma imagem. Não está faltando essa parte?

Se o que você quer é que ela tenha a imagem carregada no ImageIcon, pode carregar diretamente no BufferedImage. Você não precisa do ImageIcon.

public Componentes(){
    buffered= new BufferedImage(ImageIO.read("caminho_da_imagem"));
}

Fora isso, seu código parece ter bastante coisa “sobrando”. Pra que precisa do Graphics2D g2? Os métodos startImage e render1 não estão sendo usados em nenhuma parte. E seu paintComponent está com parâmetros incorretos e precisa de uns ajustes. Geralmente, precisa ser algo assim:

@override
protected void paintComponent(Graphics g){
  super.paintComponent(g); // sem isso, pode haver problemas "sutis"
  Graphics2D g2 = (Graphics2D) g.create();
  
  //  aqui você desenha o que quiser
  g2.drawImage(buffered, 10, 10, null);

  g2.dispose(); // libera o Graphics2D criado
} 

O Graphics2D não precisa ser um atributo da classe, pois ele geralmente só precisa existir dentro do paintComponent, e você pode passá-lo como parâmetro para outros métodos se precisar (ainda dentro do paintComponent).

Abraço.

obrigado leq to tentando não surtar com isso de inserir imagem as x ate acho q entendi mas quando vou sem cola da cambão, o q eu to vendo em tutoriais são os caras fazendo sem usar o método da classe o paint e paintComponentes, tão usando nomes aleatórios e a imagem e renderizada ja eu to me embolando todo com isso apesar to vendo q e meio simples mas não ENTENDO kkkk queria poder tirar a duvida conversando em x de digitando.
quando adiciona uma imagem num JFrame so com o Buffered eu domino, mas quando envolve esse raio do Graphics eu me embanano todo.

Deve estar surtando mesmo pra chamar de leq alguém que você não conhece. :wink:

Minha memória me enganou e o código que coloquei não funciona, pois o ImageIO.read já retorna um BufferedImage, então não precisa do new BufferedImage. Hoje consegui montar um exemplo funcional:

import javax.swing.*;
import java.awt.*;
import java.io.*;
import javax.imageio.*;
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;

public class FrameComImagem extends JFrame{

    public FrameComImagem(){
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setLayout(new BorderLayout());
        getContentPane().add(new PainelComImagem(), BorderLayout.CENTER);
    }

    class PainelComImagem extends JPanel{
        private BufferedImage imagem;

        public PainelComImagem(){
            try{
                imagem = ImageIO.read(new File("imagem.png"));
            }catch (Exception e){
                JOptionPane.showMessageDialog(null, "Erro ao carregar imagem");
            }
        }

        protected void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();
            
            g2.drawImage(imagem, 10, 10, null);

            g2.dispose();
        }
    }

    public static void main(String[] args){
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FrameComImagem().setVisible(true);
            }
        });
    }
}

Está o JFrame e o JPanel em uma classe única só pra facilitar, pode ser separado. A parte que importa é o que está dentro da classe PainelComImagem. Compilei e rodei pela linha de comando, colocando uma imagem chamada imagem.png na mesma pasta do arquivo java e do .class gerado. Se for rodar por uma ide, pode precisar ajustar o path da imagem.

Só pra desenhar uma imagem assim, o Graphics2D não é estritamente necessário, podendo usar a variável g do tipo Graphics que já existe.

Obviamente, há melhorias que podem ser feitas, como certificar que a imagem está carregada antes de tentar usar o drawImage (ou melhor ainda, terceirizar o desenho da imagem para outro método ou classe, que faz a verificação). Essa é só uma base pra você entender o processo.

Abraço.

ok q entendi obrigado só me restou uma duvida sobre esse assunto, e q em alguns tutoriais vejo a imagem sendo renderizada sem os métodos paint ou paintComponent, queria entende o processo para isso, tenho um modelo de um curso aqui mas pode me ajudar a intrepretar?

Sem você dizer quais são esses tutoriais ou um exemplo de código deles, não tenho como deduzir o que está sendo feito.

Note que eu só coloquei exemplo de carregar em um BufferedImage e desenhar no paintComponent porque seu código inicial nesse tópico segue essa linha. Esse não é o único jeito de exibir uma imagem no Java. Por exemplo, se está usando Swing, e não precisa fazer nada especial com a imagem, pode simplesmente carregá-la em um JLabel, e adicionar esse JLabel em um JFrame ou JPanel, sem precisar de paintComponent nem nada a mais.

Abraço.

to ligado as outra s maneira ja entendo de boa tava me batendo com o graphics G. mas vou mostra um modelo aqui ele nao usa o método paint nem o paintComponentes para renderizar, queria entender a logica, em outra pergunta q fiz ate me responderam bem mas ainda não assimilei 100%
/////////// classe principal //////////////
public class Game extends Canvas implements Runnable, KeyListener {

	private static final long serialVersionUID = 1L;

	public JFrame frame;
	public static final int WIDTH = 480;
	public static final int HEIGHT = 320;
	public static final int SCALE = 2;
	public int fps = 0;
	private Thread thread;
	private boolean isRunning;
	private BufferedImage image;
	public static List<Entity> entities;
	public static List<Inimigos> inimigos;
	public static List<Tiros> tiros;
	public static SpriteSheet spriteSheet;
	public static Player player;
	public static World world;
	public static Random rand; // Foi criado na classe Game por que dai pode  
	//ser usado sempre q quiser, nao precisa ficar criando instancias.
	public UI ui;

	public Game() {
		rand = new Random();
		this.addKeyListener(this);
		initFrame();
		// inicializando objetos
		ui = new UI();
		image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		// import Araylist da biblioteca java.util!
		entities = new ArrayList<Entity>();
		inimigos = new ArrayList<Inimigos>();
		tiros = new ArrayList<Tiros>();
		spriteSheet = new SpriteSheet("/Spryte32Pixels.png"); // importante!
		player = new Player(0, 0, 32, 32, spriteSheet.getSpriteSheet(0, 0, 32, 32));
		entities.add(player);
		world = new World("/miniMapa.png");
		
	}

	public void initFrame() {
		frame = new JFrame("Game RPG");
		frame.add(this);
		frame.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		frame.setIconImage(java.awt.Toolkit.getDefaultToolkit().getImage(getClass().getResource("/icone.jpg")));
		frame.pack();
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);

	}

	public synchronized void start() {

		thread = new Thread(this); // this indica em qual classe esta a thread!
		isRunning = true;
		thread.start(); // liga a thread!

	}

	public synchronized void stop() {

	}

	public static void main(String[] args) {

		Game game = new Game();
		game.start();

	}

	public void tick() {

		for (int i = 0; i < entities.size(); i++) {

			Entity e = entities.get(i);
			/*
			 * if(e instanceof Player) { System.out.println("estou renderizando o player");
			 * }
			 */
			e.tick();
		}
		for (int i = 0; i < tiros.size(); i++) {

			tiros.get(i).tick();
		}		
		
		
	}

	public void render() {
		BufferStrategy bs = this.getBufferStrategy();
		if (bs == null) {
			this.createBufferStrategy(3);
			return;
		}
		// importe graphics da biblioteca AWT;
		Graphics g = image.getGraphics();
		// Vamos inserir um plano de fundo com a cor verde no padrao RGB!
		g.setColor(new Color(0, 0, 0));
		g.fillRect(0, 0, WIDTH, HEIGHT);
		// A baixo vamso trabalhar a renderização das imagens!

		world.render(g);// esse render() pertence a classe World!

		for (int i = 0; i < entities.size(); i++) {

			Entity e = entities.get(i);
			e.render(g);
		}
		
		for (int i = 0; i < tiros.size(); i++) {

			tiros.get(i).render(g);
		}
		// vamos por aqui para que ele seja renderizado acima de todas as imagens!
		ui.render(g);
		
		// dispose e um metodo de segurança que evita ceros rerros ou bugs!
		g.dispose();
		// O grafico g recebe como valor o grafico do BufferedStrategy!
		g = bs.getDrawGraphics();
		g.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
		
		// Fonte com as muniçoes exibido na tela!
		g.setFont(new Font("arial", Font.BOLD,20));
		g.setColor(Color.white);
		g.drawString("Munição: "+player.muniçao, 15, 60);
		// Fonte com o fps exibido na tela!
		g.setFont(new Font("Arial", Font.BOLD, 20));
		g.setColor(Color.BLACK);
		g.drawString("FPS: " + fps, (WIDTH * SCALE) - 100, (HEIGHT * SCALE) - 50);
		// Chama as BufferedImage
		bs.show();
	}

	@Override
	public void run() {

		long lestTime = System.nanoTime();// tempo aproximado
		double amountOfTicks = 60; // vai resultar em 60 fps por seg
		double ns = 1000000000 / amountOfTicks;
		double delta = 0;
		int frames = 0;
		double time = System.currentTimeMillis(); // tempo decorrido
		
		requestFocus();

		while (isRunning) {
			long now = System.nanoTime(); // tempo agora(tempo presente)
			delta += (now - lestTime) / ns;
			lestTime = now;

			if (delta >= 1) {
				tick();
				render();

				frames++;
				delta--;
			}
// aqui ele usa uma converçao do tempo decorrido e cria um "thread.slemp()"!
			if (System.currentTimeMillis() - time >= 1000) {

				fps = frames;
				System.out.println("FPS: " + fps);

				frames = 0;
				time += 1000;
			}

		}

	}

///// classe auxiliar /////
public class SpriteSheet {

	private BufferedImage spritesheet;
	// o metodo construtor vai receber as imagens da pasta ress,
	// para isso pasamos como parametro String path;
	public SpriteSheet(String path) {
		// temos que colocar em um tray e catch!
		try {
			spritesheet = ImageIO.read(getClass().getResource(path));
		} catch (IOException e) {
		
			e.printStackTrace();
		}
		
	}
	// Metodo geter.
	public BufferedImage getSpriteSheet(int x, int y, int width, int height) {
		
		return spritesheet.getSubimage(x, y, width, height);
	}
	
}

O método paint é herdado dos componentes visuais do AWT, ele é o responsável por realizar a renderização do componente.

O método paintComponent é herdado dos componentes visuais do Swing, ele também é responsável pela renderização do componente.

Quando você vê um código desenhando alguma coisa sem utilizar o paint ou o paintComponent, é porque aquele código só está desenhando a imagem em memória, para depois provavelmente delegar para algum componente que vai desenhá-la utilizando o paint ou paintComponent.

2 curtidas

Nesse código ele pega o BufferStrategy do seu componente, que é um Canvas, em seguida desenha no Graphics obtido através desse BufferStrategy.

E provavelmente você está se confundindo pois você não utiliza nomes sugestivos para suas variáveis, por exemplo, primeiro você declara uma variável Graphics g para desenhar no seu BufferedImage e mais a frente você troca a referência da variável g para o Graphics do BufferStrategy.

Desse jeito é natural você se atrapalhar todo.
:man_shrugging:

1 curtida

hummm pufff agora sim entendi os nomes das variáveis nao foi eu já pequei o código assim, mas agora entendo então e o BufferedStategy q “liga” o que eu “desenho no graphics” ao canvas , que funciona como a “tela de renderizaçao”. ate q e simples nas me deu um no nas entranhas do celebro, mas ja entendo.