简体   繁体   中英

How do I make Thread.sleep() delay the execution time between two methods?

I'm working on a personal project. Ideally, my program should set a jlabels icon to a certain gif, wait for the gif to end, then set it to a blank png. My program should do this every time another label is clicked (I've used event listeners to make labels function as buttons, buttons are ugly). Unfortunately, upon "button" press, the gif is instantly replaced with the blank png, because there is no delay or waiting.

public void battle() {

ImageIcon active = new  ImageIcon(getClass().getClassLoader().getResource("resource/attacks/Animation-attackbasic_DEFAULT.gif"));
ImageIcon blank = new ImageIcon(getClass().getClassLoader().getResource("resource/attacks/Animation-blank_DEFAULT.png"));

playerAttackDisplay.setIcon(active); //This sets the Jlabel icon to the gif

try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(aqGUI.class.getName()).log(Level.SEVERE, null, ex);}

playerAttackDisplay.setIcon(blank);
}

I'd love to just put some code in a method with an int seconds parameter, then just call it whenever I need a delay. What is the most simple way to do this?

EDIT

So I've used Hovercraft Full of Eels's approach like so

public void delay(int time) {
final ImageIcon blank = new ImageIcon(getClass().getClassLoader().getResource("resource/attacks/Animation-blank_DEFAULT.png"));
new Timer(time, new ActionListener() {

public void actionPerformed(ActionEvent arg0) 
     {playerAttackDisplay.setIcon(blank);}
      }).start();}

public void battle() {
final ImageIcon I = new ImageIcon(getClass().getClassLoader().getResource("resource/attacks/Animation-attackbasic_DEFAULT.gif"));

    playerAttackDisplay.setIcon(I);
    delay(500);
}

The "battle()" method is executed every time the user presses a button in the GUI. After pressing it about twice, there is a smaller and smaller delay between the gif being set and the png being set. This results in the gif animation being cut off before it finishes. After about four or five presses, the gif is seemingly instantly cut off.

I've played around with various delay times, none of them are consistent in ALWAYS playing the gif to completion. Is there no way to get a consistent delay? For my purposes, the gif must ALWAYS play to completion at EVERY button press. How can I do this?

You ask,

How do I make Thread.sleep() delay the execution time between two methods?

And the best answer is,.... you don't.
Yours is a Swing GUI, so no, don't use Thread.sleep(...) especially on the Swing event thread as you'll end up putting your GUI entirely to sleep, which is not your goal. Use a Swing Timer instead.

Put your code to run after the delay into the Timer's ActionListener, call start() on your Timer and bingo.

For example,

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class TimerImageSwapper {
   public static final String[] IMAGE_URLS = {
      "http://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/"
      + "600px_Amaranto_con_cavallo_rampante.png/120px-600px_Amaranto_con_cavallo_rampante.png",
      "http://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/"
      + "600px_Blu_con_Croce_del_Sud.png/120px-600px_Blu_con_Croce_del_Sud.png",
      "http://upload.wikimedia.org/wikipedia/commons/thumb/1/10/"
      + "600px-Flag_of_Portugal_and_Angola_v1.png/120px-600px-Flag_of_Portugal_and_Angola_v1.png",
      "http://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/"
      + "Flag_of_Meskhetian_Turks_1.svg/120px-Flag_of_Meskhetian_Turks_1.svg.png",
      "http://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/"
      + "Greece_flag_300.png/120px-Greece_flag_300.png",
      "http://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/"
      + "National_Flag_Kingdom_of_Italy.png/120px-National_Flag_Kingdom_of_Italy.png",
      "http://upload.wikimedia.org/wikipedia/commons/thumb/9/98/"
      + "Flag_of_the_Kumukh_people.png/120px-Flag_of_the_Kumukh_people.png" };


   private ImageIcon[] icons = new ImageIcon[IMAGE_URLS.length];
   private JLabel mainLabel = new JLabel();

   private int iconIndex = 0;;

   public TimerImageSwapper(int timerDelay) throws IOException {
      for (int i = 0; i < icons.length; i++) {
         URL imgUrl = new URL(IMAGE_URLS[i]);
         BufferedImage image = ImageIO.read(imgUrl);
         icons[i] = new ImageIcon(image);
      }
      int gap = 25;
      mainLabel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));

      mainLabel.setIcon(icons[iconIndex]);

      new Timer(timerDelay, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            iconIndex++;
            iconIndex %= IMAGE_URLS.length;
            mainLabel.setIcon(icons[iconIndex]);
         }
      }).start();
   }

   public Component getMainComponent() {
      return mainLabel;
   }

   private static void createAndShowGui() {
      TimerImageSwapper timerImageSwapper;
      try {
         timerImageSwapper = new TimerImageSwapper(1000);
         JFrame frame = new JFrame("Timer Image Swapper");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(timerImageSwapper.getMainComponent());
         frame.pack();
         frame.setLocationByPlatform(true);
         frame.setVisible(true);

      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }

   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

How about...

public void battle() {

ImageIcon active = new  ImageIcon(getClass().getClassLoader().getResource("resource/attacks/Animation-attackbasic_DEFAULT.gif"));
ImageIcon blank = new ImageIcon(getClass().getClassLoader().getResource("resource/attacks/Animation-blank_DEFAULT.png"));

playerAttackDisplay.setIcon(active,Long timeToWait); //This sets the Jlabel icon to the gif

try {
Thread.sleep(timeToWait);
} catch (InterruptedException ex) {
Logger.getLogger(aqGUI.class.getName()).log(Level.SEVERE, null, ex);}

playerAttackDisplay.setIcon(blank);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM