Essa classe está no projeto Towel, para utiliza-la, entre na pagina “Towel Project” e baixe a versão mais atual para adicionar ao classpath.

JImagePanel é uma classe criada pelo ViniGodoy, é um JPanel que tem uma imagem de background no fundo e modificada por mim para ter suporte a exibir uma sequencia de imagens através do tempo.

Com ela, é possivel criar telas em Swing com imagens de fundo e ainda ter componentes por cima, diferente do que seria possivel com um JLabel, e ela é extremamente simples de usar.

Para utilizar:

  • Criar uma instancia com uma ou varias imagens;
  • Escolher o FillType, opcional, este é o modo de como a imagem vai se comportar quando a area disponivel for maior que ela, as opções são: RESIZE (crescer), CENTER (centralizado), SIDE_BY_SIDE (Lado a lado, assim como no Desktop do windows). Por default o FillType é RESIZE;
  • Adicionar ela a um Container, como um JFrame por exemplo;
  • Adicionar componentes sobre ela, isso é feito assim como em um JPanel;
  • Exibi-la.

O seguinte código representa isso.

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

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

import com.towel.swing.img.JImagePanel;

public class JImagePanelSingleTest {
	public static void main(String[] args) throws Throwable {
		JImagePanel panel = new JImagePanel(
				loadImage("/home/marcos/imgs/1.png"));

		JFrame frame = new JFrame();
		frame.setPreferredSize(new Dimension(100, 100));
		frame.add(panel);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	private static BufferedImage loadImage(String file) throws IOException {
		return ImageIO.read(new File(file));
	}
}

Com isso, temos um resultado como esse:

Se não quisermos que aumente nossa imagem, podemos usar o FillType como no seguinte código.

public class JImagePanelSingleTest {
	public static void main(String[] args) throws Throwable {
		JImagePanel panel = new JImagePanel(
				loadImage("/home/marcos/imgs/1.png"));

		panel.setFillType(JImagePanel.FillType.CENTER);

		JFrame frame = new JFrame();
		frame.setPreferredSize(new Dimension(100, 100));
		frame.add(panel);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	private static BufferedImage loadImage(String file) throws IOException {
		return ImageIO.read(new File(file));
	}
}

Com isso temos o seguinte resultado:

Para utilizar o modo em loop, basta usar o construtor que recebe um long e um array de imagens, o primeiro parametro é o tempo que levará para mudar entre uma imagem e outra em millisegundos.
Assim que criado uma Thread é disparada para atualizar as imagens, essa Thread é daemon e não vai interferir caso a Thread principal termine.
Também é possivel utilizar o FillType em modo de loop.

O código é praticamente o mesmo, ficando assim:

public class JImagePanelLoopTest {
	public static void main(String[] args) throws Throwable {
		JImagePanel panel = new JImagePanel(10, new BufferedImage[] {
				loadImage("/home/marcos/imgs/1.png"),
				loadImage("/home/marcos/imgs/2.png"),
				loadImage("/home/marcos/imgs/3.png"),
				loadImage("/home/marcos/imgs/4.png"),
				loadImage("/home/marcos/imgs/5.png"),
				loadImage("/home/marcos/imgs/6.png"),
				loadImage("/home/marcos/imgs/7.png"),
				loadImage("/home/marcos/imgs/8.png"),
				loadImage("/home/marcos/imgs/9.png"),
				loadImage("/home/marcos/imgs/10.png"),
				loadImage("/home/marcos/imgs/11.png"),
				loadImage("/home/marcos/imgs/12.png") });

		JFrame frame = new JFrame();
		frame.setPreferredSize(new Dimension(100, 100));
		frame.add(panel);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	private static BufferedImage loadImage(String file) throws IOException {
		return ImageIO.read(new File(file));
	}
}

O resultado da execução é uma animação, então não é possivel colocar uma imagem aqui.

Ainda a fazer nessa classe é o seguinte:

  • Começar a animação com um método start() por exemplo
  • Oferecer um modo para executar a animação apenas uma vez e parar em alguma imagem.