9

プログラムの実行中に日付と時刻を表示するために、プログラム内に時計を実装したいと考えています。getCurrentTime()メソッドとsを調べましたTimerが、どれも私が望むことをしていないようです。

問題は、プログラムがロードされたときに現在の時刻を取得できるが、更新されないことです。調査すべき何かについての提案は大歓迎です!

4

7 に答える 7

15

あなたがする必要があるのは、Swing のTimerクラスを使用することです。

毎秒実行し、現在の時刻で時計を更新するだけです。

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

これにより、updateClockActionが 1 秒に 1 回発火します。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);
于 2010-06-02T16:53:14.940 に答える
5

毎秒別のスレッドでテキストを更新する必要があります。

理想的には EDT (イベント ディスパッチャー スレッド) でのみ swing コンポーネントを更新する必要がありますが、私のマシンで試した後、Timer.scheduleAtFixRateを使用すると、より良い結果が得られました。

java.util.Timer http://img175.imageshack.us/img175/8876/capturadepantalla201006o.png

javax.swing.Timer バージョンは常に約 0.5 秒遅れていました。

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それを実装するタスクを残します。

于 2010-06-02T17:53:47.160 に答える
3

これは、概念的な問題があるように思われます。新しいjava.util.Dateオブジェクトを作成すると、現在の時刻に初期化されます。時計を実装する場合は、常に新しいDateオブジェクトを作成し、表示を最新の値で更新するGUIコンポーネントを作成できます。

あなたが持っているかもしれない1つの質問は、スケジュールで何かを繰り返し行う方法ですか?新しい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
于 2010-06-02T17:10:58.830 に答える
3
   public void start(){
        reset();
        ScheduledExecutorService worker = Executors.newScheduledThreadPool(3);
         worker.scheduleAtFixedRate( new Runnable(){
            public void run(){
                if( currentSecond == 60 ) {
                    reset();
                }
                time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond));
                currentSecond++;
            }
        }, 0, 1000 ,TimeUnit.MILLISECONDS );
    } 
于 2012-11-15T12:26:18.910 に答える
2

アナログ表示がお好きな方は、アナログ時計 JAppletをご利用ください。

于 2010-06-02T18:27:07.393 に答える