プログラムの実行中に日付と時刻を表示するために、プログラム内に時計を実装したいと思います。 getCurrentTime()
メソッドとTimer
sを調べましたが、どれも私が望むことをしていないようです。
問題は、プログラムがロードされたときに現在の時刻を取得できるが、更新されないことです。調べるべき何かについての提案は大歓迎です!
あなたがする必要があるのは、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());
}
}
これは毎秒時計を更新するため、最悪のシナリオでは時計が999msずれます。これを99msの最悪の場合の許容誤差に増やすには、更新頻度を増やすことができます。
Timer t = new Timer(100, updateClockAction);
毎秒別のスレッドでテキストを更新する必要があります。
理想的には、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 実装するタスクを残します。
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 );
}
これは、概念的な問題があるようです。新しい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
アナログディスプレイを好む人のために: Analog Clock JApplet 。
ここではメソッドscheduleAtFixedRate
が使用されていることに注意してください
// Current time label
final JLabel currentTimeLabel = new JLabel();
currentTimeLabel.setFont(new Font("Monospace", Font.PLAIN, 18));
currentTimeLabel.setHorizontalAlignment(JTextField.LEFT);
// Schedule a task for repainting the time
final Timer currentTimeTimer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
currentTimeLabel.setText(TIME_FORMATTER.print(System.currentTimeMillis()));
}
};
currentTimeTimer.scheduleAtFixedRate(task, 0, 1000);
Timer timer = new Timer(1000, (ActionEvent e) -> {
DateTimeFormatter myTime = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
jLabel1.setText(String.valueOf(myTime.format(now)));
});
timer.setRepeats(true);
timer.start();
これは、単純なJavaコードがスイングしない...を使用する動的クロックです。
import Java.awt.AWTException;
import Java.awt.Robot;
import Java.awt.event.KeyEvent;
import Java.util.Calendar;
import Java.util.Timer;
import Java.util.TimerTask;
import Java.util.concurrent.Delayed;
public class timer
{
public static void main(String[] args)
{
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
Robot robbie;
int second, minute, hour;
Calendar date = Calendar.getInstance();
second = date.get(Calendar.SECOND);
minute = date.get(Calendar.MINUTE);
hour = date.get(Calendar.HOUR);
System.out.println("Current time is " + hour + " : " +
minute +" : " + second);
try
{
robbie = new Robot();
robbie.keyPress(KeyEvent.VK_ALT);
robbie.keyPress(KeyEvent.VK_SHIFT);
robbie.keyPress(KeyEvent.VK_Q);
robbie.keyRelease(KeyEvent.VK_ALT);
robbie.keyRelease(KeyEvent.VK_SHIFT);
robbie.keyRelease(KeyEvent.VK_Q);
robbie.keyPress(KeyEvent.VK_C);
robbie.keyRelease(KeyEvent.VK_C);
robbie.keyPress(KeyEvent.VK_SHIFT);
robbie.keyPress(KeyEvent.VK_F10);
robbie.keyPress(KeyEvent.VK_R);
robbie.keyRelease(KeyEvent.VK_SHIFT);
robbie.keyRelease(KeyEvent.VK_F10);
robbie.keyRelease(KeyEvent.VK_R);
} catch (AWTException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 1 * 500, 1 * 500);
}
}