Остановить секундомер - PullRequest
3 голосов
/ 05 апреля 2010

У меня есть следующий код в классе JPanel, который добавляется в другой класс (JFrame). Я пытаюсь реализовать какую-то программу для секундомера.

startBtn.addActionListener(new startListener());

class startListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        Timer time = new Timer();
        time.scheduleAtFixedRate(new Stopwatch(), 1000, 1000);
    }
}

Это еще один класс, который в основном является задачей.

public class Stopwatch extends TimerTask {

    private final double start = System.currentTimeMillis();

    public void run() {
        double curr = System.currentTimeMillis();
        System.out.println((curr - start) / 1000);
    }
}

Таймер работает нормально, и это определенно далеко от завершения, но я не уверен, как кодировать кнопку остановки, которая должна остановить таймер. Любой совет по этому поводу? Кстати, я использую java.util.timer

РЕДАКТИРОВАТЬ: я хочу иметь возможность запустить его снова после остановки (без сброса таймера)

Ответы [ 4 ]

5 голосов
/ 05 апреля 2010

Если javax.swing.Timer является приемлемой альтернативой, как подсказывает @Ash, вот пример.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

/** @see http://stackoverflow.com/questions/2576909 */
public class JTimeLabel extends JLabel implements ActionListener {

    private static final String Start = "Start";
    private static final String Stop = "Stop";
    private DecimalFormat df = new DecimalFormat("000.0");
    private Timer timer = new javax.swing.Timer(100, this);
    private long now = System.currentTimeMillis();

    public JTimeLabel() {
        this.setHorizontalAlignment(JLabel.CENTER);
        this.setText(when());
    }

    public void actionPerformed(ActionEvent ae) {
        setText(when());
    }

    public void start() {
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

    private String when() {
        return df.format((System.currentTimeMillis() - now) / 1000d);
    }

    private static void create() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JTimeLabel jtl = new JTimeLabel();
        jtl.setFont(new Font("Dialog", Font.BOLD, 32));
        f.add(jtl, BorderLayout.CENTER);

        final JButton button = new JButton(Stop);
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String cmd = e.getActionCommand();
                if (Stop.equals(cmd)) {
                    jtl.stop();
                    button.setText(Start);
                } else {
                    jtl.start();
                    button.setText(Stop);
                }

            }
        });
        f.add(button, BorderLayout.SOUTH);
        f.pack();
        f.setVisible(true);
        jtl.start();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                create();
            }
        });
    }
}
5 голосов
/ 05 апреля 2010

Вы можете либо отменить все Timer, позвонив по номеру Timer.cancel(), либо отменить отдельные задачи, позвонив по номеру TimerTask.cancel().

.

В любом случае вам нужно будет сохранить ссылку на таймер и / или экземпляр задачи при его создании, чтобы ваша процедура остановки могла вызвать соответствующий метод отмены.

Обновление:

То есть, вы хотите сделать паузу в таймере? Я не думаю, что это поддерживается стандартным интерфейсом в java.util.Timer. Вы можете сделать это, добавив метод pause() (или аналогичный) к своей пользовательской задаче, записав истекшее время до этой точки, и возобновив подсчет при повторном нажатии кнопки запуска. Обратите внимание, что используя эту технику, вы не остановите само задание таймера, пока не закончите с ним полностью. Он по-прежнему работает в фоновом режиме, но вы делаете с ним все, только когда секундомер запущен и «работает» (т. Е. Какой-то флаг, указывающий состояние секундомера).

Пара заметок:

  • java.util.Timer выполняется в потоке, не являющемся EDT, поэтому, если вы взаимодействуете с переменными-членами как в таймере, так и в событиях действия Swing, вам необходимо соответствующим образом обрабатывать последствия нескольких потоков. Возможно, стоит изучить javax.swing.Timer, который вызовет события на EDT.

  • Кроме того, если вам нужен сверхточный точный секундомер, вы можете рассмотреть возможность использования System.nanoTime() вместо currentTimeMillis().

3 голосов
/ 13 февраля 2012

Я изменил источник мусора.

Обновление:

  • функция паузы
  • функция сброса

public class StopWatch extends JLabel implements ActionListener {
    private static final String Start = "Start";
    private static final String Pause = "Pause";
    private static final String Reset = "Reset";
    private boolean isRunning;
    private Timer timer = new javax.swing.Timer(100, this);
    private long initTime = System.currentTimeMillis();
    private long startTime;
    private long pauseTime;

    public StopWatch() {
        this.setHorizontalAlignment(JLabel.CENTER);
        this.setText(getCurrentTime(System.currentTimeMillis() - initTime));
    }

    public void actionPerformed(ActionEvent ae) {
        setText(getCurrentTime(System.currentTimeMillis() - startTime));
    }

    public void start() {
        if (isRunning == false) {
            startTime = System.currentTimeMillis();
        } else {
            startTime = System.currentTimeMillis() - (pauseTime - startTime);
        }

        isRunning = true;
        timer.start();
    }

    public void pause() {           
        pauseTime = System.currentTimeMillis();
        timer.stop();
    }

    public void reset() {       
        startTime = 0;
        isRunning = false;
        this.setText(getCurrentTime(System.currentTimeMillis() - System.currentTimeMillis()));
    }

    private String getCurrentTime(long time) {
        return myFormat(time);
    }

    private String myFormat(final long time) {
        final long hr = TimeUnit.MILLISECONDS.toHours(time);
        final long min = TimeUnit.MILLISECONDS.toMinutes(time
                - TimeUnit.HOURS.toMillis(hr));
        final long sec = TimeUnit.MILLISECONDS.toSeconds(time
                - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min));
        final long ms = TimeUnit.MILLISECONDS.toMillis(time
                - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min)
                - TimeUnit.SECONDS.toMillis(sec));
        return String.format("%02d:%02d:%02d.%01d", hr, min, sec, ms/100);
    }

    private static void create() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final StopWatch textLabel = new StopWatch();
        textLabel.setFont(new Font("Dialog", Font.BOLD, 32));
        f.add(textLabel, BorderLayout.CENTER);

        final JButton button = new JButton(Start);
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String cmd = e.getActionCommand();
                if (Pause.equals(cmd)) {
                    textLabel.pause();
                    button.setText(Start);
                } else {
                    textLabel.start();
                    button.setText(Pause);
                }
            }
        });

        final JButton button2 = new JButton(Reset);
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                textLabel.reset();
            }
        });

        f.add(button, BorderLayout.SOUTH);
        f.add(button2, BorderLayout.NORTH);
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                create();
            }
        });
    }
}
1 голос
/ 08 декабря 2017
long startTime = System.currentTimeMillis();
    Timer timer = new Timer(100,new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            long elapsedTime = System.currentTimeMillis()-startTime;
            long mil = elapsedTime%1000;
            long sec = elapsedTime/1000%60;
            long min = elapsedTime/60000%60;
            long hr = elapsedTime/3600000;
            label.setText(String.format("%02d:%02d:%02d.%03d", hr,min,sec,mil));
        }
    });
    timer.start();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...