Search code examples
thread-sleep

Thread.sleep (change image) Java


I have two jlabels with an image.. I try to change the image in a label when the other is clicked.. (such as a game).. I have a problem..When i write the Thread.sleep the image is not change..See the code:

public class Game extends JFrame{
private JLabel l1,l2;;
private boolean isClicked = false ,isClicked2 = false;
public Game(){
    setLayout(new FlowLayout());
    l1 = new JLabel(new ImageIcon(getClass().getResource("image1.png")));
    add(l1);
    l2 = new JLabel(new ImageIcon(getClass().getResource("image1.png")));
    add(l2);


    l1.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {}
        @Override
        public void mousePressed(MouseEvent e) {}
        @Override
        public void mouseReleased(MouseEvent e) {
            if(isClicked2){
                l1.setIcon(new ImageIcon(getClass().getResource("image2.png")));
                try {
                    Thread.sleep(1000);
                    l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
                    l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
                    isClicked2 = false;
                    isClicked = false;
            }catch(InterruptedException ex){}
            }
            else{
                l1.setIcon(new ImageIcon(getClass().getResource("image2.png")));
                isClicked = true;
            }     
        }@Override public void mouseEntered(MouseEvent e){}@Override public void mouseExited(MouseEvent e){}
    });

    l2.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {}
        @Override
        public void mousePressed(MouseEvent e) {}
        @Override
        public void mouseReleased(MouseEvent e) {
            if(isClicked){
              try {
                    l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
                    Thread.sleep(1000);
                    l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
                    l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
                isClicked = false;
                    isClicked2 = false;
              }catch(InterruptedException ex){}  
            }
            else{
                l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
                isClicked2 = true;
            }     
        }@Override public void mouseEntered(MouseEvent e){}@Override public void mouseExited(MouseEvent e){}
    });
}

public static void main(String[] args) {
    Game g = new Game();
    g.setTitle("Fint the same");
    g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    g.pack();
    g.setVisible(true);
}

}

Run it and first click the fisrt label.. After click the second label and the first will change image in 1 second but the seconf label NEVER!!


Solution

  • The changing of the images has to be done on the event thread (the thread used to process graphics events). Therefore setting the image will queue an appropriate event to be processed after your method returns. At that time though, the image has already changed back, because sleep()ing on the event thread doesn't allow any other events to be processed. As dashrb said, don't sleep() the main thread, but schedule the flip back in a Timer:

                    if (isClicked) {
    
                        l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
    
                        new javax.swing.Timer(1000, new ActionListener() {
                            @Override
                            public void actionPerformed(final ActionEvent e) {
                                l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
                                l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
                                isClicked = false;
                                isClicked2 = false;
                            }
                        }).start();
    
                    } catch (final Exception ex) {
                        ex.printStackTrace();
                    }
                } else {
                   ...