Java com café: Inserindo labels dinamicamente

Inserindo labels dinamicamente

Olá! Caro leitor. Hoje pela manhã estive olhando uns fóruns sobre Java quando me deparei com a seguinte pergunta: Como posso inserir labels dinamicamente em um JPanel? Então eu com meu espírito de colaborador, desenvolvi um pequeno código para responder a pergunta do indivíduo. Este código pode ser encontrado aqui.
Mas o que me inspirou mesmo fazer esta postagem não foi exatamente isto. Foi que me veio a cabeça modificar esse código e fazer com que ele mostrasse miniaturas de imagens, isto é, thumbnails. Sabemos que JLabels podem ser usados para exibir imagens num aplicativo, então bastava buscar as imagens num diretório e mostrá-las na tela. Portanto é isso que eu pretendo mostrar agora.
Primeiramente vamos ver o código básico para mostrar uma janela. Estou utilizando Swing pra fazer isso:

import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;


public class LabelDinamico {

public static void main(String[] args) {

JFrame janela = new JFrame("Inserindo labels dinamicamente");
janela.setBounds(0, 0, 500, 500);
janela.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
janela.setLayout(null);

//Códigos legais aqui...

janela.setVisible(true);
}
}

Não temos nada demais aí. Alguns imports, uma classe com o método main, instanciamos e mostramos uma janela. Agora vamos aos códigos legais! Duas coisas básicas antes de inserir os labels:

// Diretório contendo as imagens
File diretorio = new File("C:\\imagens");
File[] arquivos = diretorio.listFiles();

// Posicionamento dos labels
int boundX = 10;
int boundY = 10;

Primeiro pegamos o caminho do diretório que contém as imagens a serem mostradas. Se esse diretório tiver outro tipo de arquivo que não seja imagem, serão mostrados espaços vazios. Seria interessante um filtro para mostrar somente imagens, mas isso fica pra depois. Então um vetor de arquivos contém a lista das imagens. Logo em seguida declaramos variáveis que vão auxiliar no posicionamento dos labels. Isso porque os labels deverão ficar em colunas e quando chegar na largura da janela, outra fila deverá ser formada. Você vai entender melhor adiante.
Então finalmente teremos um pouco de ação! Veja como percorrer o vetor de arquivos e inserir as imagens na janela:

// Adicionando labels dinamicamente
for (int x = 0; x /* sinal de menor aqui */ arquivos.length; x++){

// Declara uma imagem com o arquivo na posição do vetor
final ImageIcon imagem = new ImageIcon(((File)arquivos[x]).getAbsolutePath());

// Declara o label
JLabel lbImagem = new JLabel()
// Esse bloco é para inserir a imagem
// e esticar de acordo com o tamanho label
{
public void paintComponent (Graphics g) {
super.paintComponent (g);
// Esses 5 sendo subtraídos é pra dar um espaço entre as imagens
g.drawImage (imagem.getImage(), 0, 0, getWidth() - 5, getHeight() - 5, null);
}
};

// Posiciona a imagem
lbImagem.setBounds(boundX, boundY, 70, 70);

// Seta o nome com o caminho da imagem
// Será usado depois para retornar o caminho quando clidado
lbImagem.setName(((File)arquivos[x]).getAbsolutePath());

// Adiciona um listener
lbImagem.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseClicked(MouseEvent arg0) {

// Pega o label que foi clicado
JLabel lb = (JLabel) arg0.getSource();
// Mosta o caminho da imagem clicada
JOptionPane.showMessageDialog(null, "O caminho da imagem é " + lb.getName(), "Imagem", JOptionPane.INFORMATION_MESSAGE);
}
});

// Prepara a posição x do próximo label
boundX += 70;

// Verifica se estourou o limite
if (boundX /* sinal de maior ou igual aqui */ janela.getWidth() - 70)
{
// Desce uma fila
boundY += 70;
boundX = 10;
}

//Adiciona o label
janela.add(lbImagem);
}

O código está bem comentado, mas ainda assim vou fazer mais algumas considerações:
  • Note que primeiramente percorremos o vetor dos arquivos utilizando um for (tive que retirar o sinal de menor pq o blogger não entende isso...)
  • Então inicialmente criamos um ImageIcon que contém a imagem do arquivo que está no vetor daquela posição.
  • Logo depois declaramos o label e utilizamos paintComponent para desenhar a imagem no label. Isto é usado para que a imagem fique do tamanho do label. A imagem será esticada (pra mais ou pra menos), para caber no label.
  • Em seguida é feito o posicionamento e a propriedade name é configurada com o caminho do arquivo. Isso é porque depois usaremos esta mesma propriedade para retornar o caminho quando a imagem for clicada. De outra forma não teria como saber qual imagem está desenhada no label. Poderíamos criar uma subclasse de label e adicionar uma ou mais propriedades adequadamente, mas deixaremos assim mesmo por enquanto.
  • Um listener é criado para mostrar a propriedade configurada anteriormente quando a imagem for clicada. Poderemos desejar fazer alguma coisa com isto depois.
  • Finalmente a posição é configurada, levando em conta o tamanho da janela. O label é adicionado na janela.
Vejamos como ficou:

Outra coisa que podemos fazer é pegar todos os componentes da janela (no caso, os labels) e exibir suas propriedades ou modificar alguma coisa. Veja como fazer isto:

for (int x = 0; x /* sinal de menor aqui */ labels.length; x++){
if (labels[x] instanceof JLabel)
{
// Mostra todos o name dos labels
System.out.println(((JLabel)labels[x]).getName());
}
}

Bom, é isso que eu tinha pra passar pra vocês hoje. O código completo você encontra aqui. Sei que falta muita coisa ainda pra que esse código se torne um componente de verdade e possa ser reutilizado mas o primeiro passo está dado. Espero que tenham gostado e até a próxima!

Nenhum comentário:

Postar um comentário