Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带条件的停止计时器仅在第一次工作?_Java_Netbeans_Timer_Timertask - Fatal编程技术网

Java 带条件的停止计时器仅在第一次工作?

Java 带条件的停止计时器仅在第一次工作?,java,netbeans,timer,timertask,Java,Netbeans,Timer,Timertask,我正在写一个“谁想成为百万富翁”的游戏,我已经准备好了一切,只是计时器有问题 游戏是这样运行的:如果用户答对了问题,他/她就会继续。如果没有,比赛就结束了,他们可以选择再次比赛 当游戏第一次运行时,它很好,计时器做它应该做的事情——从30秒开始倒计时,显示秒数 但是,当用户单击“再次播放”按钮时,上一个计时器将继续使用新的计时器。像这样: -timerA在用户丢失之前还有20秒(以a表示) -timerB在下一次玩游戏时开始(用b表示) 输出:20A29B19A28B18A27B17A26B。。

我正在写一个“谁想成为百万富翁”的游戏,我已经准备好了一切,只是计时器有问题

游戏是这样运行的:如果用户答对了问题,他/她就会继续。如果没有,比赛就结束了,他们可以选择再次比赛

当游戏第一次运行时,它很好,计时器做它应该做的事情——从30秒开始倒计时,显示秒数

但是,当用户单击“再次播放”按钮时,上一个计时器将继续使用新的计时器。像这样:

-timerA在用户丢失之前还有20秒(以a表示)

-timerB在下一次玩游戏时开始(用b表示)

输出:20A29B19A28B18A27B17A26B。。。。。。。2a 11b 1a 10b 9b 8b 7b 6b 5b 4b 2b 1b

这是我的定时器类,叫做倒计时:

  import java.util.Timer;
  import java.util.TimerTask;

  public class CountDown {

      static Timer timer;
      public static int seconds = 30;

      public CountDown() {
          timer = new Timer();
          timer.schedule(new DisplayCountdown(), 0, 1000);
      }

      class DisplayCountdown extends TimerTask {

          int seconds = 30;

          public void run() {

                  if (seconds == 0) {
                      timer.cancel();
                      timer.purge();
                      return;
                  }

              if (seconds > 0) {
                  PlayFrame.timer.setText("" + seconds); //jLabel used to display seconds
                  seconds--;
                  if (seconds < 30) {
                      if (PlayFrame.right == true) { //check if question was answered correctly
                          System.out.print("true"); //testing purposes
                          PlayFrame.right = false;
                          PlayFrame.showQuestion();
                          PlayFrame.startTimer();
                          seconds = 0;
                          //break;
                      }
                      else if (PlayFrame.right == false) {
                          //break;
                      }
                  }      

                  else if (seconds == 0) { //if time runs out its automatic wrong answer
                      PlayFrame.wrong();
                      //break;
                  }      

                  else {
                      PlayFrame.wrong();
                      PlayFrame.timer.setText(null);
                      timer = new Timer();
                      //break;
                  }
              }
              System.out.println(seconds); // for testing purposes only
          }
      }
  }
请提供帮助,如果您需要更多信息,请咨询

您不应该与Swing应用程序一起使用。对于这些,您应该使用,因为这将尊重Swing事件线程。因此,你的问题是没有意义的,我建议你扔掉所有的计时代码,试试合适的计时器。您可以在此处找到教程:

接下来,您将希望摆脱代码正在使用的所有静态方法和字段,并将它们更改为实例字段和方法

显示JLabel中剩余时间的摆动计时器示例:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TimerExample {

   private static void createAndShowGui() {
      Gui mainPanel = new Gui();

      JFrame frame = new JFrame("TimerExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

class Gui extends JPanel {
   private static final long serialVersionUID = 1L;
   private static final String PRESS_BUTTON = "Press Button ";
   private static final String PRESS_BUTTON_AGAIN = "Press Button Again Within %02d Seconds!";
   private static final String YOU_LOSE = "You Lose!";
   private static final String YOU_WIN = "You Win!";
   private static final int PREF_W = 250;
   private static final int PREF_H = 100;
   private static final int TOTAL_SECONDS = 20;
   private static final int ONE_SECOND = 1000;

   private int elapsedSeconds = 0;
   private JLabel timerLabel = new JLabel(PRESS_BUTTON);
   private JButton button = new JButton("Button");
   private Timer myTimer;

   public Gui() {
      JPanel btnPanel = new JPanel();
      btnPanel.add(button);

      setLayout(new BorderLayout());
      add(btnPanel, BorderLayout.CENTER);
      add(timerLabel, BorderLayout.SOUTH);

      button.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            if (myTimer != null && myTimer.isRunning()) {
               myTimer.stop();
               myTimer = null;
               timerLabel.setText(YOU_WIN);               
            } else {
               elapsedSeconds = 0;
               myTimer = new Timer(ONE_SECOND, new TimerListener());
               myTimer.start();
               String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS); 
               timerLabel.setText(text);
            }
         }
      });
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         elapsedSeconds++;

         if (elapsedSeconds == TOTAL_SECONDS) {
            myTimer.stop();
            timerLabel.setText(YOU_LOSE);
         } else {
            String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS - elapsedSeconds);
            timerLabel.setText(text );
         }
      }
   }
}

我建议您将计时器声明移动到JFrame中,然后为每次需要计时器时创建“DisplayCountdown”类的新实例,并将“Timer.schedule(new DisplayCountdown(),0,1000);”行移到别处


如果清除计时器对象,它将被完全重置,因此您无需创建新的计时器对象,只需添加新的计时器任务。

已解决,感谢链接

以及有关swing计时器的更多帮助(用于本主题的未来搜索)

publicstaticvoidstarttimer(){
listener=新建ActionListener(){
@凌驾
已执行的公共无效操作(操作事件){
系统输出打印(“操作”);
timerLabel.setText(“+”秒);
秒--;
系统输出打印项次(秒);
如果(秒<0){
系统输出打印(“零”);
错();
}
}
};
displayTimer=新计时器(1000,侦听器);
displayTimer.setInitialDelay(1);
displayTimer.start();
if(right==true){
系统输出打印(“真”);
displayTimer.stop();
右=假;
秒=30;
displayTimer=新计时器(10000,侦听器);
displayTimer.setDelay(10000);
displayTimer.setInitialDelay(1);
displayTimer.start();
}
else if(right==null){
系统输出打印(“空”);
displayTimer.stop();
秒=30;
displayTimer=新计时器(10000,侦听器);
displayTimer.setInitialDelay(1);
displayTimer.setDelay(10000);
displayTimer.start();
}
}

这并不理想。我所有的东西都在工作,只是前一个计时器不会停止,即使我对它调用cancel()和purge()。(是的,我是一个新手)我被动作听众搞糊涂了;因为我是用Netbeans编写的,所以它会自动为我编写。@codeaddick:这不是它是否理想的问题。这是错误的,可能不起作用,纯粹而简单。如果ActionListeners让您感到困惑,我在上面链接的同一教程中有一节介绍如何使用ActionListeners。当然,如果你被卡住了,你随时可以回到这里展示你的尝试。@CodeAddict我也是一个非常新的程序员,我必须说Swing Timer是一个不错的选择。我只用过一次,但很简单。即使我没有使用GUI,我也会在util定时器上使用它。你真的应该接受气垫船的建议。这家伙给出了一个非常好的解释@David Kroukamp我理解这个论点,但我想我可能会选择与SwingWorker一起使用Swing计时器,以防止长时间运行的任务在EDT上结束。然而,你是对的,使用util定时器也可以避免这种情况。@DavidKroukamp:在EDT上运行的任何东西都是如此。摆动计时器严格用于计时,仅此而已。如果代码调用长时间运行的进程,则该进程需要位于后台线程上。Swing计时器的优点是,它的ActionListener代码在EDT上运行,从而使您不必排队等待可运行的。另一方面,对于时间关键型代码,有时还有比util计时器更好的方法?如果我将
timer.schedule
行移到
run
块中,会有帮助吗?如何添加新的TimerTask?很抱歉,Timer类将我与purge()和cancel()方法混淆。在主应用程序中,我想您将其称为PlayFrame,您将创建一个专用计时器变量,并且每当启动计时器时,都会添加以下行:“Timer.schedule(new DisplayCountdown(),0,1000);”。当倒计时结束时,如果超时,它会自动清除自身,因此除了在DisplayCountdown类和PlayFrame类的错误函数运行时,您不需要在任何地方调用purge。我得到一个包含倒计时的封闭实例。DisplayCountdown是必需的(因为DisplayCountdown在倒计时类中).好的,但如果答案正确,我希望计时器完全消失,不要再使用它,并使用“取消”和“清除”功能创建一个新计时器。使用“取消”和“清除”功能与创建新计时器的操作完全相同,但应能更好地清除存储的内存。在多线程中,最好使用提供的清除功能,如wi就我所知,记忆并没有被清除。它一直在运行,直到达到0才会停止。就像一个执行任务的女人,直到达到
    // Reset Everything
    PlayFrame.count = 0;
    PlayFrame.answer = new String();
    PlayFrame.count = 0;
    PlayFrame.right = false;
    PlayFrame.winnings = 0;
    CountDown.seconds = 30;
    CountDown.timer = new Timer();
    CountDown.timer.cancel();
    CountDown.timer.purge();
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TimerExample {

   private static void createAndShowGui() {
      Gui mainPanel = new Gui();

      JFrame frame = new JFrame("TimerExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

class Gui extends JPanel {
   private static final long serialVersionUID = 1L;
   private static final String PRESS_BUTTON = "Press Button ";
   private static final String PRESS_BUTTON_AGAIN = "Press Button Again Within %02d Seconds!";
   private static final String YOU_LOSE = "You Lose!";
   private static final String YOU_WIN = "You Win!";
   private static final int PREF_W = 250;
   private static final int PREF_H = 100;
   private static final int TOTAL_SECONDS = 20;
   private static final int ONE_SECOND = 1000;

   private int elapsedSeconds = 0;
   private JLabel timerLabel = new JLabel(PRESS_BUTTON);
   private JButton button = new JButton("Button");
   private Timer myTimer;

   public Gui() {
      JPanel btnPanel = new JPanel();
      btnPanel.add(button);

      setLayout(new BorderLayout());
      add(btnPanel, BorderLayout.CENTER);
      add(timerLabel, BorderLayout.SOUTH);

      button.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            if (myTimer != null && myTimer.isRunning()) {
               myTimer.stop();
               myTimer = null;
               timerLabel.setText(YOU_WIN);               
            } else {
               elapsedSeconds = 0;
               myTimer = new Timer(ONE_SECOND, new TimerListener());
               myTimer.start();
               String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS); 
               timerLabel.setText(text);
            }
         }
      });
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         elapsedSeconds++;

         if (elapsedSeconds == TOTAL_SECONDS) {
            myTimer.stop();
            timerLabel.setText(YOU_LOSE);
         } else {
            String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS - elapsedSeconds);
            timerLabel.setText(text );
         }
      }
   }
}
public static void startTimer() {
    listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            System.out.print("action");
            timerLabel.setText("" + seconds);
            seconds--;
            System.out.println(seconds);
            if (seconds < 0){
                System.out.print("zero");
                wrong();
            }
        }
    };
    displayTimer = new Timer(1000, listener);
    displayTimer.setInitialDelay(1);
    displayTimer.start();

    if (right == true){
        System.out.print("true");
        displayTimer.stop();
        right = false;
        seconds = 30;
        displayTimer = new Timer(10000, listener);
        displayTimer.setDelay(10000);
        displayTimer.setInitialDelay(1);
        displayTimer.start();
    }
    else if (right == null){
        System.out.print("null");
        displayTimer.stop();
        seconds = 30;
        displayTimer = new Timer(10000, listener);
        displayTimer.setInitialDelay(1);
        displayTimer.setDelay(10000);
        displayTimer.start();
    }
}