Stop timer with conditional only works first time?

大憨熊 提交于 2019-12-02 01:21:11

You shouldn't be using java.util.Timer with a Swing application. For these you should use javax.swing.Timer since this will respect the Swing event thread. Thus your question is moot, and I suggest that you throw all of your timing code out and try the proper timer. You can find the tutorial here: Swing Timer Tutorial

Next you'll want to get rid of all the static methods and fields that your code is using and change them over for instance fields and methods.

An example of a Swing Timer displaying remaining time in a 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 );
         }
      }
   }
}

What I recommend doing is moving the Timer declaration into the JFrame, and then creating a new instance of your "DisplayCountdown" class for each time the timer is needed, and move the "timer.schedule(new DisplayCountdown(), 0, 1000);" line elsewhere.

If you purge a timer object, it is completely reset, so you don't need to create a new timer object, only add a new TimerTask.

Solved, thanks for the link sage88! http://albertattard.blogspot.com/2008/09/practical-example-of-swing-timer.html

And for more help on swing timers (for future searches of this topic) http://www.asjava.com/swing/java-timer-tutorial/

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();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!