import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.Hashtable; /* * SliderDemo2.java is a 1.4 application that requires all the files * in the images/doggy directory. */ public class SliderDemo2 extends JPanel implements ActionListener, WindowListener, ChangeListener { //Set up animation parameters. static final int FPS_MIN = 0; static final int FPS_MAX = 30; static final int FPS_INIT = 15; //initial frames per second int frameNumber = 0; int NUM_FRAMES = 14; ImageIcon[] images = new ImageIcon[NUM_FRAMES]; int delay; Timer timer; boolean frozen = false; //This label uses ImageIcon to show the doggy pictures. JLabel picture; public SliderDemo2() { super(new BorderLayout()); delay = 1000 / FPS_INIT; //Create the slider. JSlider framesPerSecond = new JSlider(JSlider.VERTICAL, FPS_MIN, FPS_MAX, FPS_INIT); framesPerSecond.addChangeListener(this); framesPerSecond.setMajorTickSpacing(10); framesPerSecond.setPaintTicks(true); //Create the label table. Hashtable labelTable = new Hashtable(); //PENDING: could use images, but we don't have any good ones. labelTable.put(new Integer( 0 ), new JLabel("Stop") ); //new JLabel(createImageIcon("images/stop.gif")) ); labelTable.put(new Integer( FPS_MAX/10 ), new JLabel("Slow") ); //new JLabel(createImageIcon("images/slow.gif")) ); labelTable.put(new Integer( FPS_MAX ), new JLabel("Fast") ); //new JLabel(createImageIcon("images/fast.gif")) ); framesPerSecond.setLabelTable(labelTable); framesPerSecond.setPaintLabels(true); framesPerSecond.setBorder( BorderFactory.createEmptyBorder(0,0,0,10)); //Create the label that displays the animation. picture = new JLabel(); picture.setHorizontalAlignment(JLabel.CENTER); picture.setAlignmentX(Component.CENTER_ALIGNMENT); picture.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLoweredBevelBorder(), BorderFactory.createEmptyBorder(10,10,10,10))); updatePicture(0); //display first frame //Put everything together. add(framesPerSecond, BorderLayout.LINE_START); add(picture, BorderLayout.CENTER); setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); //Set up a timer that calls this object's action handler. timer = new Timer(delay, this); timer.setInitialDelay(delay * 7); //We pause animation twice per cycle //by restarting the timer timer.setCoalesce(true); } /** Add a listener for window events. */ void addWindowListener(Window w) { w.addWindowListener(this); } //React to window events. public void windowIconified(WindowEvent e) { stopAnimation(); } public void windowDeiconified(WindowEvent e) { startAnimation(); } public void windowOpened(WindowEvent e) {} public void windowClosing(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} /** Listen to the slider. */ public void stateChanged(ChangeEvent e) { JSlider source = (JSlider)e.getSource(); if (!source.getValueIsAdjusting()) { int fps = (int)source.getValue(); if (fps == 0) { if (!frozen) stopAnimation(); } else { delay = 1000 / fps; timer.setDelay(delay); timer.setInitialDelay(delay * 10); if (frozen) startAnimation(); } } } public void startAnimation() { //Start (or restart) animating! timer.start(); frozen = false; } public void stopAnimation() { //Stop the animating thread. timer.stop(); frozen = true; } //Called when the Timer fires. public void actionPerformed(ActionEvent e) { //Advance the animation frame. if (frameNumber == (NUM_FRAMES - 1)) { frameNumber = 0; } else { frameNumber++; } updatePicture(frameNumber); //display the next picture if ( frameNumber==(NUM_FRAMES - 1) || frameNumber==(NUM_FRAMES/2 - 1) ) { timer.restart(); } } /** Update the label to display the image for the current frame. */ protected void updatePicture(int frameNum) { //Get the image if we haven't already. if (images[frameNumber] == null) { images[frameNumber] = createImageIcon("images/doggy/T" + frameNumber + ".gif"); } //Set the image. if (images[frameNumber] != null) { picture.setIcon(images[frameNumber]); } else { //image not found picture.setText("image #" + frameNumber + " not found"); } } /** Returns an ImageIcon, or null if the path was invalid. */ protected static ImageIcon createImageIcon(String path) { java.net.URL imgURL = SliderDemo2.class.getResource(path); if (imgURL != null) { return new ImageIcon(imgURL); } else { System.err.println("Couldn't find file: " + path); return null; } } /** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { //Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); //Create and set up the window. JFrame frame = new JFrame("SliderDemo2"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. SliderDemo2 animator = new SliderDemo2(); animator.setOpaque(true); //content panes must be opaque frame.setContentPane(animator); //Display the window. frame.pack(); frame.setVisible(true); animator.startAnimation(); } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }