/** * Copyright (c) 2009 Mark S. Kolich * http://mark.koli.ch * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package com.kolich.swing; import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; import org.apache.commons.io.IOUtils; public class SwingTimerDemo extends JFrame implements Runnable { private static final long serialVersionUID = 1074695564475467373L; private static final String FRAME_TITLE = "javax.swing.Timer Demo"; private static final int TIMER_THREAD_INTERVAL = 200; // 200 ms private Timer timer_; public SwingTimerDemo() { super(FRAME_TITLE); } public void run() { final JPanel viewPort = new JPanel(); viewPort.setLayout(new GridLayout(2,1)); viewPort.setOpaque(true); viewPort.setBackground(Color.BLACK); viewPort.setPreferredSize(new Dimension(300, 500)); getContentPane().add(viewPort); final JLabel ani = new JLabel(); ani.setHorizontalAlignment(JLabel.CENTER); ani.setVerticalAlignment(JLabel.CENTER); ani.setIcon(AnimateLoop.getFirstFrame()); viewPort.add(ani); final JButton control = new JButton("Start"); viewPort.add(control); control.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { if(timer_ == null) { timer_ = new Timer(TIMER_THREAD_INTERVAL, new AnimateLoop(ani)); timer_.start(); control.setText("Stop"); } else { timer_.stop(); timer_ = null; control.setText("Start"); } } }); /* final JButton exit = new JButton("Exit"); viewPort.add(exit); exit.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); */ pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setResizable(false); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new SwingTimerDemo()); } /** * This is the class that actually does the animation work. * @author Mark Kolich * */ public static class AnimateLoop implements ActionListener { private static final String FRAMES_DIR = "frames"; private static final String GIF_EXTENSION = ".gif"; private static final File framesDir__; private static final List frames__; static { frames__ = new ArrayList(); framesDir__ = new File(FRAMES_DIR); // Find all of the .gif files in our frames/ directory. // We only animated over .gif files; you can, of course, // animate over whatever image types you want as long // as they can be converted into an ImageIcon. final File[] frames = framesDir__.listFiles(new FileFilter() { public boolean accept ( File file ) { return !file.getName().startsWith(".") && file.getName().endsWith(GIF_EXTENSION); } }); for(File frame : frames) { frames__.add(getImageIcon(frame)); } } private JLabel label_; private int index_; /** * The JLabel is the label this animation * loop will animate on. * @param label */ public AnimateLoop(JLabel label) { label_ = label; index_ = 0; } /** * Called every time the action event fires. */ @Override public void actionPerformed(ActionEvent e) { label_.setIcon(frames__.get(index_)); index_ += 1; if(index_ > frames__.size() - 1) { index_ = 0; } } private static final ImageIcon getImageIcon(final File f) { FileInputStream fis = null; try { fis = new FileInputStream(f); return new ImageIcon(IOUtils.toByteArray(fis)); } catch (Exception e) { return null; } finally { try { if(fis != null) { fis.close(); } } catch (IOException e) { } } } public static final ImageIcon getFirstFrame() { return frames__.get(0); } } }