Reputation: 519
In the overridden function for my JFrame
:
@Override
protected void paintComponent(Graphics g) {
BufferedImage imagePerson;
try {
imagePerson = ImageIO.read(new File("errol.gif"));
} catch (IOException e) {
imagePerson = null;
}
g.drawImage(imagePerson, i * increment, j * increment - 1, null);
}
How can I change this so the animation on the gif is shown (without using threading). I have spent many hours trying to get this to work but to no avail.
Upvotes: 8
Views: 24892
Reputation: 2551
I think using ImageIcon is the easiest way to render an animated GIF image on a JPanel. However, if you want to render the image on the JPanel, you should use BufferedImage for that component.
You can draw any image format using the ImageIO class in Java, as shown below:
public void loadImage(File imgFile) {
try {
ImageInputStream stream = ImageIO.createImageInputStream(imgFile);
ImageReader reader = ImageIO.getImageReadersByFormatName("your_image_type").next();
reader.setInput(stream);
int numFrames = reader.getNumImages(true);
for (int i = 0; i < numFrames; i++) {
BufferedImage frame = reader.read(i);
// do something
}
reader.dispose();
} catch (IOException e) {
e.printStackTrace();
}
}
The 'your_image_type' can be found using methods like the ones below:
public String getReaderTypeByExtention(File imgFile)
{
String fileName = imgFile.getName();
String fileExtension = "";
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex > 0) {
fileExtension = fileName.substring(dotIndex + 1).toLowerCase();
}
if(fileExtension.toLowerCase().equals("jpg") || fileExtension.toLowerCase().equals("jpeg"))
return "jpeg";
if(fileExtension.toLowerCase().equals("png"))
return "png";
if(fileExtension.toLowerCase().equals("gif"))
return "gif";
return fileExtension;
}
The full sample code for this task is provided below (created using NetBeans):
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/GUIForms/JFrame.java to edit this template
*/
package com.tobee.image;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
/**
*
* @author
*/
public class GIFLoader extends javax.swing.JFrame {
/**
* Creates new form GIFLoader
*/
public GIFLoader() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
loadImagePane = new LoadImagePane();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Load");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout loadImagePaneLayout = new javax.swing.GroupLayout(loadImagePane);
loadImagePane.setLayout(loadImagePaneLayout);
loadImagePaneLayout.setHorizontalGroup(
loadImagePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, loadImagePaneLayout.createSequentialGroup()
.addContainerGap(427, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap())
);
loadImagePaneLayout.setVerticalGroup(
loadImagePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, loadImagePaneLayout.createSequentialGroup()
.addContainerGap(320, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(34, 34, 34))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(loadImagePane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(loadImagePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
String initDir = System.getProperty("opencv.mov.dir");
String title = "choose ";
((LoadImagePane)loadImagePane).stopLoadImage();
JFileChooser jFileChooser = new JFileChooser(initDir);
FileNameExtensionFilter extFilter = new FileNameExtensionFilter("images", "jpg", "jpeg", "png", "gif");
//jFileChooser.setFileFilter(extFilter);
jFileChooser.addChoosableFileFilter(extFilter);
int returnType = jFileChooser.showDialog(this, title);
switch(returnType)
{
case JFileChooser.APPROVE_OPTION:
File chooseFile = jFileChooser.getSelectedFile();
((LoadImagePane)loadImagePane).loadImage(chooseFile);
break;
case JFileChooser.CANCEL_OPTION:
JOptionPane.showConfirmDialog(null,
"Canceled file selection by user",
title,
JOptionPane.INFORMATION_MESSAGE);
break;
default:
//do nothing
}
}//GEN-LAST:event_jButton1ActionPerformed
private static class LoadImagePane extends JPanel
{
private ArrayList<BufferedImage> frames = new ArrayList<>();
private BufferedImage currentFrame;
private boolean isStop = false;
private Thread freamThread;
private final Runnable gifRunner = new Runnable()
{
@Override
public void run() {
while(!isStop)
{
ArrayList<BufferedImage> framesInner = frames;
if (!framesInner.isEmpty()){
for(BufferedImage bi : framesInner)
{
currentFrame = bi;
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
}
repaint();
}
}
else
{
System.out.println("Cam fream is empty..");
}
}
}
};
public void stopLoadImage()
{
isStop = true;
}
public String getReaderTypeByExtention(File imgFile)
{
String fileName = imgFile.getName();
String fileExtension = "";
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex > 0) {
fileExtension = fileName.substring(dotIndex + 1).toLowerCase();
}
if(fileExtension.toLowerCase().equals("jpg") || fileExtension.toLowerCase().equals("jpeg"))
return "jpeg";
if(fileExtension.toLowerCase().equals("png"))
return "png";
if(fileExtension.toLowerCase().equals("gif"))
return "gif";
return fileExtension;
}
public void loadImage(File imgFile) {
try {
isStop = false;
frames.clear();
ImageInputStream stream = ImageIO.createImageInputStream(imgFile);
ImageReader reader = ImageIO.getImageReadersByFormatName(getReaderTypeByExtention(imgFile)).next();
reader.setInput(stream);
int numFrames = reader.getNumImages(true);
for (int i = 0; i < numFrames; i++) {
BufferedImage frame = reader.read(i);
frames.add(frame);
}
reader.dispose();
} catch (IOException e) {
e.printStackTrace();
}
freamThread = new Thread(gifRunner);
freamThread.setDaemon(true);
freamThread.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (currentFrame != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - currentFrame.getWidth()) / 2;
int y = (getHeight() - currentFrame.getHeight()) / 2;
g2d.drawImage(currentFrame, x, y, this);
g2d.dispose();
currentFrame.flush();
//System.out.println("opened....11");
}
}
@Override
public Dimension getPreferredSize() {
if (currentFrame == null) {
return super.getPreferredSize();
} else {
int w = currentFrame.getWidth();
int h = currentFrame.getHeight();
return new Dimension(w, h);
}
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(GIFLoader.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(GIFLoader.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(GIFLoader.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(GIFLoader.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GIFLoader().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JPanel loadImagePane;
// End of variables declaration//GEN-END:variables
}
Upvotes: 0
Reputation: 1475
Check this example for displaying an animated gif in Swing. you dont have to use any threads:
Icon imgIcon = new ImageIcon(this.getClass().getResource("ajax-loader.gif"));
JLabel label = new JLabel(imgIcon);
label.setBounds(668, 43, 46, 14); // for example, you can use your own values
frame.getContentPane().add(label);
Upvotes: 1