2010-04-05 2 views
3

У меня есть следующий код в классе 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); 
    } 
} 

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

EDIT: Я хочу, чтобы иметь возможность запустить его снова после его остановки (без таймера сбрасывается)

ответ

5

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

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

Update:

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

Несколько примечаний:

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

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

+0

К сожалению, это не совсем то, что я искал. Я редактировал свой вопрос. –

5

Если 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(); 
      } 
     }); 
    } 
} 
3

Я изменил источник trashgod.

обновление:

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

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
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(); 
Смежные вопросы