0

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);
}
user725455
  • 465
  • 10
  • 36
  • Does all the `Timer` Objects doing the same thing, or each `Timer` Object is meant to do something different ? Or you simply want the `Timer` Object to revert back to the starting state, when a new job is selected from the `JComboBox` – nIcE cOw Mar 18 '12 at 14:48
  • edited:each timer object makes same thing just refresh screen.When a new job is selected from combobox if it s active state setTimer method is called.I added setTimer method declaration – user725455 Mar 18 '12 at 16:10
  • What does `graph.trigger(jobId)` do? Is this a long-running task? What is your typical timerTriggerTime interval? I'm not sure if your question is answerable given the information provided so far. – Hovercraft Full Of Eels Mar 18 '12 at 16:32
  • graph.trigger refreshes JFreechart ChartPanel.So it shows new data.timerTriggerTime is milisecond of timer delay(10000) – user725455 Mar 18 '12 at 16:34
  • I have to wonder if your problem is one of reference, that you're trying to stop the wrong timer object. We may need to see more code to determine if this is so, and best would be an [sscce](http://sscce.org). – Hovercraft Full Of Eels Mar 18 '12 at 16:45
  • Hovercraft Full of Eeels.Noticed that when one timer is running another timer is starting to work.But I am using global variable why it keeps reference to previous timer – user725455 Mar 18 '12 at 17:09

3 Answers3

2

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();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
1

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);
        }
    }

}
black panda
  • 2,842
  • 1
  • 20
  • 28
-1

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...

Perry Monschau
  • 883
  • 8
  • 22
  • 1
    Sorry but this code violates so many Swing threading rules that it should be taken out back and shot. Down vote. – Hovercraft Full Of Eels Mar 18 '12 at 16:28
  • Why stop function does not work.This can be a bug or this is my fault? – user725455 Mar 18 '12 at 16:30
  • @user725455: I would take what Perry says with a grain of salt. I've not run into the javax.swing.Timer being buggy at all, and in all likelihood the bug or misinterpretation of how Swing works is in your code. The trick is in trying to find the problem. Keep looking, keep isolating code, and you'll find it. – Hovercraft Full Of Eels Mar 18 '12 at 16:33
  • Inside stop function, Do I have to also set notifierTimer = null.I think it keeps reference to timer, Also status is not running it continues to work. – user725455 Mar 18 '12 at 16:44
  • Hovercraft, I would like to know which rules these are. Perhaps you could write up a quick example code for a working Timer? – Perry Monschau Mar 18 '12 at 17:55