// Scott DeRuiter 5/2/02 // ThreeD.java // Animates a series of images import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class ThreeD extends JApplet { private Image [] image; private int i, pausetime; ImagePanel canvas; private JButton runit, stopit, onestep; private JTextField describeField, numberField; JScrollBar imagenumber; private JSlider speed; public ThreeD ( ) { image = new Image [40]; i = 0; pausetime = 100; } public void init() { setBackground ( Color.black ); canvas = new ImagePanel ( ); getContentPane().add( canvas, BorderLayout.CENTER ); JPanel top = new JPanel ( new GridLayout ( 1, 3 ) ); getContentPane().add ( BorderLayout.NORTH, top ); runit = new JButton ( "RUN / RESUME" ); top.add ( runit ); runit.addActionListener ( canvas ); stopit = new JButton ( "STOP" ); top.add ( stopit ); stopit.addActionListener ( canvas ); onestep = new JButton ( "NEXT STEP" ); top.add ( onestep ); onestep.addActionListener ( canvas ); imagenumber = new JScrollBar(JScrollBar.VERTICAL, 1, 1, 0, 40); imagenumber.addAdjustmentListener ( canvas ); getContentPane().add ( BorderLayout.EAST, imagenumber ); JPanel bottom = new JPanel ( ); getContentPane().add ( BorderLayout.SOUTH, bottom ); describeField = new JTextField ( "Pause Time:" ); describeField.setEditable ( false ); bottom.add ( describeField ); numberField = new JTextField ( 4 ); numberField.setText ( "" + pausetime ); bottom.add ( numberField ); speed = new JSlider ( 5, 405, 100 ); speed.addChangeListener ( canvas ); speed.setMajorTickSpacing ( 100 ); speed.setMinorTickSpacing ( 25 ); speed.setPaintTicks ( true ); bottom.add ( speed ); for ( int i = 0; i < image.length; i++ ) { image[i] = getImage ( getDocumentBase ( ), "pic" + (i + 1) + ".jpg" ); WaitForImage ( this, image[i] ); } } public void WaitForImage ( JApplet component, Image image ) { MediaTracker tracker = new MediaTracker ( component ); try { tracker.addImage ( image, 0 ); tracker.waitForID ( 0 ); } catch ( InterruptedException e ) { e.printStackTrace ( ); } } public Insets getInsets ( ) { return new Insets ( 5, 5, 5, 5 ); } class ImagePanel extends JPanel implements ActionListener, AdjustmentListener, ChangeListener, Runnable { private Thread runner; private boolean running, justonestep; public ImagePanel ( ) { justonestep = false; } public void paintComponent ( Graphics g ) { Font num = new Font ( "Serif", Font.BOLD, 26 ); g.setFont ( num ); super.paintComponent ( g ); g.drawImage ( image[i], 0, 0, this.getWidth( ), this.getHeight( ), this ); g.drawString ( "" + (i + 1), getWidth( ) - 40, 40 ); } void startRunning() { if (running) return; runner = new Thread(this); running = true; runner.start(); } void stopRunning() { running = false; } public void run() { runit.setEnabled ( false ); stopit.setEnabled ( true ); while ( running ) { i++; if ( i == 40 ) i = 0; imagenumber.setValue ( i ); repaint ( ); if ( justonestep ) running = false; else { Thread.yield(); Pause ( pausetime ); } } justonestep = false; running = false; runit.setEnabled ( true ); stopit.setEnabled ( false ); } public void Pause ( int milli ) { try { Thread.sleep ( milli ); } catch ( InterruptedException e ) { } } public void actionPerformed ( ActionEvent evt ) { String command = evt.getActionCommand ( ); if ( command.equals ( "RUN / RESUME" ) ) startRunning ( ); else if ( command.equals ( "STOP" ) ) stopRunning ( ); else if ( command.equals ( "NEXT STEP" ) ) { justonestep = true; startRunning ( ); } } public void adjustmentValueChanged( AdjustmentEvent e ) { i = imagenumber.getValue ( ); repaint ( ); } public void stateChanged ( ChangeEvent changeevent ) { if ( changeevent.getSource() == speed ) { pausetime = speed.getValue ( ); numberField.setText ( "" + pausetime ); } } } }