Динамические часы в Яве

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

Проблема в том, что я могу узнать текущее время, когда программа загружается, но она никогда не обновляется. Будем весьма благодарны за любые предложения по поводу того, на что обратить внимание!

8
задан jjnguy 2 June 2010 в 17:22
поделиться

4 ответа

Что вам нужно сделать, так это использовать класс Swing Timer .

Просто запустите его каждую секунду и обновите часы, указав текущее время.

Timer t = new Timer(1000, updateClockAction);
t.start();

Это приведет к срабатыванию updateClockAction один раз в секунду. Он будет работать на EDT.

Вы можете сделать updateClockAction аналогичным следующему:

ActionListener updateClockAction = new ActionListener() {
  public void actionPerformed(ActionEvent e) {
      // Assumes clock is a custom component
      yourClock.setTime(System.currentTimeMillis()); 
      // OR
      // Assumes clock is a JLabel
      yourClock.setText(new Date().toString()); 
    }
}

Поскольку это обновляет часы каждую секунду, в худшем случае часы будут отключены на 999 мс. Чтобы увеличить допустимую погрешность до 99 мс, вы можете увеличить частоту обновления:

Timer t = new Timer(100, updateClockAction);
14
ответ дан 5 December 2019 в 06:22
поделиться

Для тех, кто предпочитает аналоговый дисплей: Аналоговые часы JApplet .

2
ответ дан 5 December 2019 в 06:22
поделиться

Вы должны обновлять текст в отдельном потоке каждую секунду.

В идеале вы должны обновлять компонент Swing только в EDT (поток диспетчера событий), но после того, как я попробовал его на своей машине, использование Timer.scheduleAtFixRate дало мне лучшие результаты:

java.util. Таймер http://img175.imageshack.us/img175/8876/capturadepantalla201006o.png

Версия javax.swing.Timer всегда отставала примерно на полсекунды:

javax.swing.Timer http: //img241.imageshack .us / img241 / 2599 / capturadepantalla201006.png

Я действительно не знаю почему.

Вот полный исходный код:

package clock;

import javax.swing.*;
import java.util.*;
import java.text.SimpleDateFormat;

class Clock {
    private final JLabel time = new JLabel();
    private final SimpleDateFormat sdf  = new SimpleDateFormat("hh:mm");
    private int   currentSecond;
    private Calendar calendar;

    public static void main( String [] args ) {
        JFrame frame = new JFrame();
        Clock clock = new Clock();
        frame.add( clock.time );
        frame.pack();
        frame.setVisible( true );
        clock.start();
    }
    private void reset(){
        calendar = Calendar.getInstance();
        currentSecond = calendar.get(Calendar.SECOND);
    }
    public void start(){
        reset();
        Timer timer = new Timer();
        timer.scheduleAtFixedRate( new TimerTask(){
            public void run(){
                if( currentSecond == 60 ) {
                    reset();
                }
                time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond ));
                currentSecond++;
            }
        }, 0, 1000 );
    }
}

Вот измененный исходный код с использованием javax.swing.Timer

    public void start(){
        reset();
        Timer timer = new Timer(1000, new ActionListener(){
        public void actionPerformed( ActionEvent e ) {
                if( currentSecond == 60 ) {
                    reset();
                }
                time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond ));
                currentSecond++;
            }
        });
        timer.start();
    }

Возможно, мне следует изменить способ вычисления строки с датой, но я не думаю, что здесь проблема

Я прочитал, что, начиная с Java 5, рекомендуется: ScheduledExecutorService Я оставляю вам задачу реализовать его.

5
ответ дан 5 December 2019 в 06:22
поделиться

Похоже, что у вас концептуальная проблема. Когда вы создаете новый объект java.util.Date, он инициализируется текущим временем. Если вы хотите реализовать часы, вы можете создать компонент GUI, который постоянно создает новый объект Date и обновляет дисплей последним значением.

Один из вопросов, который может возникнуть у вас, - как многократно выполнять что-то по расписанию? Можно создать бесконечный цикл, который создает новый объект Date, а затем вызывает Thread.sleep(1000), чтобы каждую секунду получать последнее время. Более элегантный способ сделать это - использовать TimerTask. Обычно вы делаете что-то вроде:

private class MyTimedTask extends TimerTask {

   @Override
   public void run() {
      Date currentDate = new Date();
      // Do something with currentDate such as write to a label
   }
}

Затем, чтобы вызвать ее, вы делаете что-то вроде:

Timer myTimer = new Timer();
myTimer.schedule(new MyTimedTask (), 0, 1000);  // Start immediately, repeat every 1000ms
2
ответ дан 5 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: