Quero Aprender sobre como trabalhar com imagens em Java

cara so usa .add(imagelabel); se vc estiver usando um painel como nesse caso vc esta usando nem um painel recomento usar getContentPane().add(imagelabel);

desculpa @samlis acho que agora entendi vc quer mover a imagem com o mouse é isso ?

não, só mover a imagem a partir das coordenadas dentro do frame

Por exemplo, eu quero colocar a imagem no canto superior direito que seria o ponto (0,0) no Frame. A questão de usar o mouse ou o teclado não tem muito importância, pq eu só quero por enquanto mover a imagem de lugar mesmo, sobre eventos de mouse ou teclado eu já tenho um pouco de noção

É mai ou menos isso aqui, mover a imagem ali pro outro espaço vazio:

O problema persiste, eu só consigo fazer a mudança de posição fazendo isso que eu fiz no código, fora isso ele não muda de posição.

package trabalhandoimagens;

import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.util.Timer;
import java.util.TimerTask;

public class TrabalhandoImagens {
static Timer timer = new Timer();
static int i = 0;
static int x = 0;
static int y = 0;
public static void main(String[] args) throws IOException {
        final Janela janela = new Janela();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if(i<5){
                    i++;
                    janela.moverLabel(x,y);
                    x += 10;
                    y -= 10;
                } else {
                    timer.cancel();
                    System.out.println("Acabou");
                }
            }
        }, 100, 1000);
    }

}

final class Janela extends JFrame {
InputStream stream = getClass().getResourceAsStream("/imagens/Habitante_Zul.png");
Image image;
ImageIcon imagem;
JLabel imagelabel;

public Janela() throws IOException {
    this.image = ImageIO.read(stream);
    imagem = new ImageIcon(image);
    imagelabel = new JLabel();
    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(600,600);
    setVisible(true);
    this.getContentPane().add(imagelabel);
    
    imagelabel.setLayout(null);
    imagelabel.setIcon(imagem);
}
public void moverLabel(int x, int y) {
    imagelabel.setBounds(x,y,imagelabel.getWidth(),imagelabel.getHeight());
}

vc pode chamar esse método qual sua imagem for clicada, ele pega a posição X e Y do seu curso do mouse adiciona a posição da imagem meno o seu tamanho dividido por dois

private void imagelabelMouseDragged(java.awt.event.MouseEvent evt) {                                      
    imagelabel.setLocation(evt.getX() + imagelabel.getLocation().x - imagelabel.getWidth() / 2, evt.getY() + imagelabel.getLocation().y - imagelabel.getHeight()  / 2);
}

vc esta fazendo um jogo? pq se estiver vc pode criar um repositório no GitHub e passar o link por aqui, eu ajudo

Então eu só consigo mexer uma imagem ou definir a posição dela através de Eventos como por exemplo mouse e teclado?

E na verdade eu to querendo aprender o máximo que eu poder sobre Java, antes de tentar criar um jogo. Isso que to fazendo é só pra aprender mesmo.

Não, você pode alterar de acordo com qualquer parâmetro que quiser (ex: de x em x segundos, ou quando um determinado estado interno do seu programa mudar).

O método setLocation(), por exemplo, precisa de 2 parâmetros: posição X e posição Y. Pra ele, não importa de onde vieram esses valores (do mouse, teclado, rede, temperatura do processador, um timer, distância da Terra até a Lua…). O setIcon() precisa de um ImageIcon, mas de onde vem esse ImageIcon não importa para ele. Isso é uma das mágicas do encapsulamento :wink: .

Dica: se quer criar um jogo razoavelmente dinâmico, os componentes Swing não são adequados. Geralmente, em jogos, se desenha diretamente sobre um canvas (ex: sobrescrevendo o método paintComponent de um JPanel). Você estará melhor servido usando uma biblioteca/engine como a LibGdx, mas não recomendo até você estar mais confortável com Java.

Abraço.

Sim, eu entendo, o que quis dizer é que por exemplo, quando eu uso o setBounds ou setLocation ou qualquer outro metódo desses direto no main ou qualque outro lugar que não seja um evento, timertask a imagem não, ele fica sempre localizada numa posicao centralizada na tela no caso no lado esquerdo, então por exemplo, eu vo programar ele e só tem o Jframe e o JLabel com a imagem e eu use o setLocation direto no main, uma linha só com jLabelImagem.setLocation(100,100), ele simplesmente não vai executar o método, eu preciso colocar esse método dentro de um timer, ou um evento para ai sim ser chamado e executado.

Depende de como você está fazendo isso. Você está usando a thread do Swing ao criar seu JFrame?

Mas esse é o tipo de problema que você pode ter ao tentar usar o Swing dessa maneira, setando a posição absoluta dos componentes. Lembrando também que o Swing não é thread safe, então se você usar timers ou threads para controlar os elementos na tela, pode ter esse e outros problemas.

Abraço.

Aqui, eu peguei e fiz de uma forma que ele não coloca a imagem no ponto (100,100) e para qualquer outro ponto ou parâmetros que usar, ele não vai mudar, mesmo usando setBounds, setAlignment.

Você não está usando a thread do Swing quando cria sua janela (veja o main no código abaixo). Isso é recomendado para evitar problemas no Swing, pois ele não é thread safe.

Afora isso, não sei o problema com seu código. Ma segue um exemplo quase idêntico ao seu. Basta colocar uma imagem na mesma pasta da classe (fiz isso pra simplificar, pode ser um caminho maior).

import javax.swing.*;
import java.awt.EventQueue.*;
import java.awt.Dimension;

public class FrameComImagem extends JFrame{
	
	private JLabel labelParaImagem;
	
	public FrameComImagem(){
		setTitle("Teste");
		setLayout(null);
		setPreferredSize( new Dimension(800, 800));
		setSize(getPreferredSize());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		labelParaImagem = new JLabel();
		getContentPane().add(labelParaImagem);
		
		this.carregarImagem();
		this.posicionarLabel(100, 100);
	}
	
	public void carregarImagem(){
		ImageIcon imagem = new ImageIcon("imagem.png"); // pode usar InputStream aqui, se preferir. Ou mesmo um File()
		
		labelParaImagem.setIcon(imagem);
		
		// muda o tamanho do JLabel para comportar a imagem
		labelParaImagem.setBounds(0, 0, imagem.getImage().getWidth(null), imagem.getImage().getHeight(null));
	}
	
	public void posicionarLabel(int px, int py){
		labelParaImagem.setLocation(px, py);
	}

	public static void main(String args[]){
		// cria uma thread para rodar a janela: altamente recomendavel
		java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FrameComImagem().setVisible(true);
            }
        });
	}
}

Não se apegue ao jeito como o ImageIcon recebe a imagem (coloquei só o path, ao invés de usar InputStream). Desde que a imagem esteja carregada no ImageIcon, deve funcionar normalmente.

Dica: quando for postar código, poste só o código, não uma imagem dele. Copie do editor e cole na resposta, e use a tag code.

Abraço.

1 curtida

Agr entendo melhor como funciona, é que eu não sei muita coisa sobre threads, então eu não sei o que é uma thread safe e provavelmente o meu código não deve ter funcionado por não usar mesmo uma thread, obg mesmo.

Mas nessa parte do ImageIcon ele não funcionou, ele não conseguiu exibir a imagem, o código funcionou, abriu o frame e tudo mas a imagem não apareceu e muito menos deu algum erro, provavelmente não ta conseguindo carregar a imagem desse jeito.

Mas resolvi usando um getClass().getResource(“Habitante_Zul.png”) dentro do new ImageIcon(Aqui). Depois que fiz isso, funcionou perfeitamente.

O motivo de eu colocar a imagem é pq eu queria mostrar a imagem do JFrame junto para melhorar a visualização do que acontece. Mas obg, vou lembrar de fazer isso, no máximo se precisar mostrar uma imagem vou colocar só do que eu quero realmente mostrar como JFrame está funcionando.

@samlis
Eu estive vendo um canal de um rapaz que fez um vídeo explicando como armazenar no banco de dados e depois visualizar… creio que pode ser útil para você.
Está em espanhol, mas tirei algumas dúvidas em outros assuntos complexos que está tentando realizar e vendo ele fazer me tirou algumas dúvidas. Segue abaixo o video :wink:

Inserindo Imagens no Banco de Dados

Espero ter ajudado!

1 curtida

O que as classes BufferedImage, Graphics e Graphics2D fazem e como eu faço para poder utilizar os metodos dessas classes?

https://docs.oracle.com/javase/tutorial/2d/basic2d/index.html

1 curtida

@staroski, estava aqui pensando em qual a melhor classe para representar uma imagem no Java. Você ainda recomendaria a “java.awt.Image”?

O que você entende por “melhor classe”?

Boa pergunta. Eu imagino que seja menos incompatibilidade de ser aceita.

Então, se não sabe o que é melhor pra ti, escolha aquilo que te atende.
Todas as classes de imagem do Java estendem java.awt.Image.
Não sei o que você pretende fazer mas na prática eu sempre utilizei BufferedImage e VolatileImage.

2 curtidas

Bacana. Obrigado pela explicação!

[]'s