Search code examples
javaswingjlabelanimated-gifimageicon

switching between a gif and a png on a JLabel


I'm trying to make a Russian Roulette game and I'm trying to change the JLabel to the gif of the revolver spinning. However, I can change it from the gif but not back to the picture of the revolver. Or is there a way to play the gif only once and have it stop then change it to another gif?

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class RussianRoulette extends JFrame {

    private int Chamber;
    private int BulletPos;
    private boolean ButtonToggle;
    JButton Fire = new JButton("Fire");
    JButton Spin = new JButton("Spin");
    JLabel Gun = new JLabel();
    public RussianRoulette() {
    ButtonToggle = true;
    Chamber = (int) (Math.random() * 6 + 1);
    BulletPos = 0;
    JFrame frame = new JFrame();
    frame.getContentPane().setLayout(null);
    Gun.setBounds(0, 0, 500, 375);
    Fire.setBounds(25, 375, 100, 100);
    Spin.setBounds(350, 375, 100, 100);
    ImageIcon imgThisImg = new ImageIcon("Revolver2.png");
    Gun.setIcon(imgThisImg);                
    Spin.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
                spinGun();
                sleep(600);

            }
        });

        Fire.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                fireGun();
            }
        });
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.add(Gun);
        frame.add(Fire);
        frame.add(Spin);
        frame.setResizable(true);
        frame.setSize(500, 500);
        Image im = Toolkit.getDefaultToolkit().getImage("icon.png");
        frame.setIconImage(im);
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setTitle("Russian Roulette");

    }

    public void spinGun() {
         ImageIcon imgThisImg = new ImageIcon("SpinRevolver.gif");
         Gun.setIcon(imgThisImg);
         sleep(600);
        AudioPlayer player3 = new AudioPlayer("Spin.wav");
        player3.play();
        BulletPos = (int) (Math.random() * 6 + 1);
    }

    public void fireGun() {

        if (ButtonToggle == false) {
            AudioPlayer player5 = new AudioPlayer("Click.wav");
            player5.play();
        }

        if (Chamber == BulletPos && ButtonToggle == true) {
            AudioPlayer player2 = new AudioPlayer("Shot.wav");
            player2.play();
            ButtonToggle = false;
        } else {
            Chamber++;
            CheckNum();
            AudioPlayer player = new AudioPlayer("Click.wav");
            player.play();
        }
    }

    public void CheckNum() {
        if (Chamber > 6) {
            Chamber = 1;
        }
    }

    public void reload()
    {
        //play reload animation
        ButtonToggle = true;
    }

        public void sleep(int ammount)
        {
            try {
                Thread.sleep(ammount);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

}

Solution

  • So, based on feedback, you want the animation to start running on a button click and stop automatically after a given period of time...

    Probably the simplest solution would be to use a javax.swing.Timer, otherwise you'll need to set yourself up as some kind of ImageObserver and interrupt the various events coming from the image...like I said, simpler...

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class SpiningLabel {
    
        public static void main(String[] args) {
            new SpiningLabel();
        }
    
        public SpiningLabel() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private ImageIcon spin;
            private ImageIcon still;
    
            private JLabel label;
            private Timer timer;
            private JButton button;
    
            public TestPane() {
                spin = new ImageIcon("spin.gif");
                still = new ImageIcon("still.png");
    
                label = new JLabel(still);
                button = new JButton("Allons-y!");
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        label.setIcon(spin);
                        button.setEnabled(false);
                        timer.restart();
                    }
                });
                timer = new Timer(2000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        label.setIcon(still);
                        button.setEnabled(true);
                    }
                });
                timer.setRepeats(false);
    
                setLayout(new BorderLayout());
                add(label);
                add(button, BorderLayout.SOUTH);
            }
        }
    
    }