Включить, чтобы остановить таймер
У меня есть приложение, которое я хочу обновить экран в некоторые периоды. Пользователь будет выбирать задачу в комбинированном режиме, если задание является активной задачей, таймер будет запущен. Так что существует только один таймер.
Я пытаюсь остановить таймер, когда из комбо выбрано новое задание. Вот функция остановки таймера. Кажется, это не работает для некоторых случаев. Но я не мог поймать случай. Хотя таймер не является нулевым и работает, он не останавливается. Он работает в начале программы, через некоторое время не работает.
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);
}
3 ответа
Это как для OP, так и для Perry Monschau: это пример "рабочего" Swing Timer, который запускается и останавливается по команде. Я еще не закончил с этой программой, поскольку я пытаюсь сделать ее более похожей на MVC, но, тем не менее, запустите ее, и вы увидите, что она работает нормально.
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();
}
});
}
}
Можете ли вы просто использовать один таймер и добавлять / удалять слушателей по мере необходимости? Этот тип вещей работает для вас?
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);
}
}
}
Да, я не использую Timer по таким причинам, как глючит.
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;
}
}
Должно сработать...