简体   繁体   English

Java GUI倒计时

[英]Java gui countdown

I need to make a GUI where a worker enters a station (a spot on the panel) and stays there for a set amount of seconds, shown in a countdown about the workers head (so, once the workers moves to the spot, the station's label shows 3s -> 2s -> 1s and then the worker leaves, and the label reverts back to "OPEN"). 我需要制作一个GUI,在该GUI中,工人进入工位(面板上的某个位置)并停留在那里一定的时间,如工人头倒数所示(因此,一旦工人移至现场,工位的位置标签显示3s-> 2s-> 1s,然后工作人员离开,标签恢复为“ OPEN”)。 I'm having trouble with making this happen, as I'm not too good with the Timer(s?) that Java has. 我很难做到这一点,因为我对Java的Timer不太满意。 I tried with something like this: 我尝试过这样的事情:

Timer timer = new Timer(1000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            //change label text/color, decrement countdown
            panel.repaint();
            Thread.sleep(1000);
        }
    });

But I can't reach the number of seconds to count down from from inside the timer, and I'm not sure how to pass that value to the timer. 但是我无法达到从计时器内部倒数的秒数,而且我不确定如何将该值传递给计时器。 If someone can help me out, I'd really appreciate it. 如果有人可以帮助我,我将非常感激。

Get rid of the Thread.sleep() . 摆脱Thread.sleep() That's what the 1000 in Timer(1000, new ActionListener() does. It sets an interval for each timer event. Every time a timer event is fired, the actionPerformed is called. So you need to determine what needs to happen every "tick", and put that code in the actionPerformed . Maybe something like 这就是在1000Timer(1000, new ActionListener()一样。它设定的时间间隔为每个定时器事件,每一个定时器事件被触发时, actionPerformed被调用。所以,你需要确定什么需要做的每一个“滴答” ,然后将该代码放入actionPerformed

Timer timer = new Timer(1000, new ActionListener() {
    private int count = 5;
    @Override
    public void actionPerformed(ActionEvent e) {
        if (count <= 0) {
            label.setText("OPEN");
            ((Timer)e.getSource()).stop();
            count = 5;
        } else {
            label.setText(Integer.toString(count);
            count--;
        }
    }
});

You need to decide when to call timer.start() . 您需要确定何时调用timer.start()

Problem #1: You are calling Thread.sleep() from within the Swing GUI thread. 问题#1:您正在从Swing GUI线程中调用Thread.sleep()。 That causes the thread to stop taking input and freeze. 这导致线程停止接受输入并冻结。 Delete that line. 删除该行。 It does you no good! 这对你没有好处! While you are at it, delete the repaint call as well. 在使用它时,也请删除重画调用。

Now that that's said and done, instead of creating an anonymous instance of ActionListener, you can create an actual class that implements ActionListener and provides a constructor. 现在已经说完了,而不是创建一个匿名的ActionListener实例,您可以创建一个实现ActionListener并提供构造函数的实际类。 That constructor can have as an argument the number of seconds you want to start counting down. 该构造函数可以将要开始倒数的秒数作为参数。 You can declare that class inside the method you are using, or you can declare it inside the class. 您可以在使用的方法中声明该类,也可以在该类中声明它。

Here's a skeletal example: 这是一个骨架的例子:

public class OuterClass {
   JLabel secondsLabel = ...;
   Timer myTimer;

   private void setupTimer(int numSecondsToCountDown) {
      secondsLabel.setText(Integer.toString(numSecondsToCountDown));
      myTimer = new Timer(1000, new CountdownListener(numSecondsToCountDown));
      myTimer.start();
   }

   // ...
   class CountdownListener implements ActionListener {
      private int secondsCount;

      public CountdownListener(int startingSeconds) { secondsCount = startingSeconds; }

      public void actionPerformed(ActionEvent evt) {
         secondsLabel.setText(Integer.toString(secondsCount);
         secondsCount--;

         if (secondsCount <= 0) { // stop the countdown
            myTimer.stop();
         }
      }
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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