タイマーでアクションを実行させるには?
ところで、先ほどのソースコードで、ちょっと不思議な書き方をしている部分があったのに気づいたでしょうか。それはimportの部分です。
import java.util.*;
import java.util.Timer;
最初にjava.utilパッケージをすべてimportしているのに、その後でわざわざまたjava.util.Timerをimportしていますね。なぜ、こんな無駄なことをしているのでしょう?
実は、これは無駄なことではないのです。実際にやってみるとわかりますが、このimport java.util.Timer;を削除すると、コンパイル時にエラーが発生するはずです。実をいえば、「Timer」という名前のクラスは、java.util以外にもあるのです。それは、javax.swing.Timerというもの。先のサンプルではjava.utilとjavax.swingの両方をimportしていたため、使用するTimerがどちらのパッケージのものかわからなくなってしまうのです。そこで、わざわざ「import java.util.Timer;」と記述することで、「こちらのTimerを使っているんだ」ということを明確にしたのですね。
では、もう一方のjavax.swingにあるTimerは一体何なのでしょう? これは「タイマーでアクションを実行する」ためのものなのです。このTimerは、インスタンスを作成するとき、実行するActionListenerと呼び出し間隔をそれぞれ指定することで、そのActionListenerのactionPerformedを定期的に実行させることができるのです。
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer; // ★
public class Sample extends JFrame {
JLabel label;
JButton button;
public static void main(String[] args) {
new Sample();
}
public Sample() {
this.setSize(200,100);
this.setLayout(new BorderLayout());
label = new JLabel();
label.setFont(new Font("Dialog",
Font.BOLD,24));
this.getContentPane().add(label,
BorderLayout.CENTER);
button = new JButton("Click");
MyAction act = new MyAction();
button.addActionListener(act);
this.getContentPane().add(button,
BorderLayout.SOUTH);
new Timer(10000,act).start();
this.setVisible(true);
}
class MyAction implements ActionListener {
public void actionPerformed(ActionEvent ev){
SimpleDateFormat sf =
new SimpleDateFormat("hh:mm:ss");
GregorianCalendar cal =
new GregorianCalendar();
label.setText(sf.format(cal.getTime()));
}
}
}
JButtonをクリックすると現在の時刻が表示される。押さないでいると10秒ごとに表示が更新される。 |
これも簡単な例を挙げておきましょう。先ほどのサンプルを修正し、JButtonをクリックすると現在の時刻がJLabelに表示されるようにしてみました。クリックしなくとも、10秒経過ごとにタイマーで表示が更新されるようになっています。
ここではActionListenerは「MyAction」というクラスとして用意してあります。これをTimerとJButtonにそれぞれ設定をしてあるわけです。また、今度はjavax.swing.Timerを利用するので、「import javax.swing.Timer;」を用意してjava.util.Timerが使われないように注意しましょう。
【Javadocリファレンス】
java.util.Timerクラス
java.util.TimerTaskクラス
javax.swing.Timerクラス