Enable to stop timer

こ雲淡風輕ζ 提交于 2019-12-25 17:44:30

问题


I have an application that I want to refresh screen in some periods.User will select a task in combo, if job is active task, a timer will be started.So only one timer exists.

I am trying to stop timer when a new task is selected from combo.Here is stop timer function. It seems it does not work for some cases.But I could not catch the case. Although timer is not null and is Running, it does not stop.it works at the begining of program, after a while does not work.

public void stopTimer() {
    logger.error("Timer is ready to stop: ");
    if (notifierTimer != null) {
        logger.error("Coalesce: " + notifierTimer.isCoalesce());
        logger.error("Running: " + notifierTimer.isRunning());
    }
    if (notifierTimer != null && notifierTimer.isRunning()) {
        notifierTimer.stop();
        logger.error("Timer stopped for job id");
    }
}


public void setTimer(final long jobId) {
    final int timerTriggerTime = 10000;

    ActionListener listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            graph.trigger(jobId);
            logger.error("Graph Triggered: " + jobId);
        }
    };
    /** create Timer */
        notifierTimer = new Timer(timerTriggerTime, listener);
        /** start timer */
        notifierTimer.start();
        /** run timer for each user specifed time */
        notifierTimer.setDelay(timerTriggerTime);
        logger.error("Timer started for job id" + jobId);
}

回答1:


This one is for both the OP and for Perry Monschau: This is an example of a "working" Swing Timer, one that starts and stops on command. I'm not yet done with this program as I'm trying to make it more MVC-like, but nevertheless run it and you'll see it functions fine.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class CountDownTimer extends JPanel {
   private static final int BL_GAP = 5;
   private static final int MS_PER_SEC = 1000;
   private static final int SEC_PER_MIN = 60;
   private static final int MIN_PER_HR = 60;
   private static final float DISPLAY_PTS = 54f;
   private static final String DISPLAY_FORMAT_STR = "%02d:%02d:%02d:%01d";
   private static final float SPINNER_FONT_PTS = 16f;
   public static final int TIMER_DELAY = 50;
   public static final Color NEGATIVE_COLOR = Color.red;
   private StartAction startAction = new StartAction();
   private ResetAction resetAction = new ResetAction(startAction);
   private QuitAction quitAction = new QuitAction();
   private final Action[] btnActions = { resetAction , startAction ,
         quitAction };
   private JSpinner hourSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 10,
         1));
   private JSpinner minuteSpinner = new JSpinner(new SpinnerNumberModel(0, 0,
         60, 1));
   private JSpinner secondSpinner = new JSpinner(new SpinnerNumberModel(0, 0,
         60, 1));
   private JLabel displayField = new JLabel("", SwingConstants.CENTER);
   private long startTime;
   private long currentTime;
   private long deltaTime;
   private long setTimeToComplete;
   private boolean negative = false;
   private Timer timer;
   private int hours;
   private int min;
   private int sec;
   private int msec;
   private JFrame frame;

   public CountDownTimer(JFrame frame) {
      this.frame = frame;
      displayField.setFont(displayField.getFont().deriveFont(Font.BOLD,
            DISPLAY_PTS));
      displayField.setBorder(BorderFactory.createLineBorder(Color.blue, 2));

      setLayout(new BorderLayout(BL_GAP, BL_GAP));
      int eb = 2;
      setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
      add(displayField, BorderLayout.NORTH);
      add(createGuiBody());
      showTimeLeft();
   }

   private JPanel createGuiBody() {
      JPanel bodyPanel = new JPanel();
      bodyPanel.setLayout(new BoxLayout(bodyPanel, BoxLayout.PAGE_AXIS));
      bodyPanel.add(createSpinnerPanel());
      bodyPanel.add(createButtonPanel());
      return bodyPanel;
   }

   private JPanel createButtonPanel() {
      JPanel innerBtnPanel = new JPanel(new GridLayout(1, 0, BL_GAP, 0));
      for (Action action : btnActions) {
         innerBtnPanel.add(new JButton(action));
      }
      JPanel btnPanel = new JPanel(new BorderLayout());
      btnPanel.add(innerBtnPanel);
      return btnPanel;
   }

   private JPanel createSpinnerPanel() {
      Font font = hourSpinner.getFont().deriveFont(Font.BOLD, SPINNER_FONT_PTS);
      hourSpinner.setFont(font);
      minuteSpinner.setFont(font);
      secondSpinner.setFont(font);
      JPanel spinnerPanel = new JPanel();
      spinnerPanel.add(new JLabel("Hrs:"));
      spinnerPanel.add(hourSpinner);
      spinnerPanel.add(Box.createHorizontalStrut(BL_GAP * 2));
      spinnerPanel.add(new JLabel("Min:"));
      spinnerPanel.add(minuteSpinner);
      spinnerPanel.add(Box.createHorizontalStrut(BL_GAP * 2));
      spinnerPanel.add(new JLabel("Secs:"));
      spinnerPanel.add(secondSpinner);

      return spinnerPanel;
   }

   private void showTimeLeft() {
      int oldMin = min;
      hours = (int) (deltaTime / (MS_PER_SEC * SEC_PER_MIN * MIN_PER_HR));
      min = (int) (deltaTime / (MS_PER_SEC * SEC_PER_MIN) % MIN_PER_HR);
      sec = (int) (deltaTime / (MS_PER_SEC) % SEC_PER_MIN);
      msec = (int) (deltaTime % MS_PER_SEC);

      String displayString = String.format(DISPLAY_FORMAT_STR, hours, min, sec,
            msec / 100);
      displayField.setText(displayString);

      if (Math.abs(oldMin - min) > 0) {
         String title = frame.getTitle().replaceAll("\\d", "");
         title = String.format("%02d " + title, min);
         frame.setTitle(title);
      }
   }

   private class ResetAction extends AbstractAction {
      private StartAction startAction;

      public ResetAction(StartAction startAction) {
         super("Reset");
         putValue(MNEMONIC_KEY, KeyEvent.VK_R);
         this.startAction = startAction;
      }

      public void actionPerformed(ActionEvent evt) {
         if (startAction != null
               && startAction.getValue(NAME).equals(StartAction.STOP)) {
            startAction.actionPerformed(new ActionEvent(evt.getSource(),
                  ActionEvent.ACTION_PERFORMED, StartAction.STOP));
         } else if (timer != null && timer.isRunning()) {
            timer.stop();
         }
         displayField.setForeground(null);
         deltaTime = (Integer) hourSpinner.getValue();
         deltaTime = MIN_PER_HR * deltaTime
               + (Integer) minuteSpinner.getValue();
         deltaTime = SEC_PER_MIN * deltaTime
               + (Integer) secondSpinner.getValue();
         deltaTime = MS_PER_SEC * deltaTime;
         showTimeLeft();
         negative = false;
         timer = new Timer(TIMER_DELAY, new TimerListener());
      }
   }

   private class StartAction extends AbstractAction {
      public static final String START = "Start";
      public static final String STOP = "Stop";

      public StartAction() {
         putValue(MNEMONIC_KEY, KeyEvent.VK_S);
         putValue(NAME, START);
      }

      public void actionPerformed(ActionEvent evt) {
         if (timer == null) {
            return;
         }
         if (getValue(NAME).equals(START)) {
            putValue(NAME, STOP);

            startTime = System.currentTimeMillis();
            currentTime = startTime;
            setTimeToComplete = deltaTime;
            timer.start();
         } else {
            if (timer != null && timer.isRunning()) {
               putValue(NAME, START);
               timer.stop();
            }
         }
      }
   }

   private class QuitAction extends AbstractAction {
      public QuitAction() {
         super("Quit");
         putValue(MNEMONIC_KEY, KeyEvent.VK_Q);
      }

      public void actionPerformed(ActionEvent arg0) {
         if (timer != null && timer.isRunning()) {
            timer.stop();
         }
         frame.dispose();
      }
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent arg0) {
         currentTime = System.currentTimeMillis();
         deltaTime = setTimeToComplete - currentTime + startTime;

         if (deltaTime < 0) {
            deltaTime = -deltaTime;
            if (!negative) {
               negative = true;
               displayField.setForeground(NEGATIVE_COLOR);
            }
         }
         showTimeLeft();
      }
   }

   private static void createAndShowGui() {
      String title = "Count Down Timer";
      title = JOptionPane.showInputDialog("Timer Title?", title);
      JFrame frame = new JFrame(title);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new CountDownTimer(frame));
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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



回答2:


Can you just use one Timer and add/remove listeners as needed? Does this type of thing work for you?

class Example {
    // try using one timer.
    Timer timer = new Timer(1000, null); // initial


    // don't know if you only call these methods
    // inside the Swing thread. If you do, you can
    // remove synchronized.
    public synchronized void startRefresh(int jobId) {
        // just to make sure nothing is running...
        stopRefresh(); 

        int triggerTime = 1000;
        ActionListener listener = ...;

        timer.setDelay(triggerTime);
        timer.setInitialDelay(triggerTime);

        timer.addActionListener(listener);
        timer.start();
    }

    public synchronized void stopRefresh() {
        timer.stop();

        for (ActionListener listener : timer.getActionListeners()) {
            timer.removeActionListener(listener);
        }
    }

}



回答3:


Yeah I don't use Timer for reasons such as being buggy like that.

public class MyTimer extends Thread {
    boolean kill = false;
    int tick = 10;
    ActionListener al;

    public MyTimer(int tick, ActionListener al) {
        this.tick = tick;
        this.al = al;
    }

    public void run() {
        try {
            while(!kill) {
                al.actionPerformed(new ActionEvent(this,ActionEvent.ACTION_PERFORMED,"tick"));
                Thread.sleep(tick);
            }
        } catch (InterruptedException e) {
        }
    }

    public void stop()
    {
        kill = true;
    }
}

Should work...



来源:https://stackoverflow.com/questions/9759115/enable-to-stop-timer

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