概要
JavaFX で簡単なストップウォッチを作ってみます。
スクリーンショット
起動直後
Start
”Start” を押すとカウントアップが始まります。
カウントアップ中は ”Start” が ”Stop” になっていて、そのボタンを押すとカウントアップが停止します。
Reset を押せばカウントをクリアします。以上、何の変哲もないストップウォッチでした。
解説
Component 本体
Button を継承して実装しました。Component 自体をクリックしてもカウントアップのコントロールが可能になっています。
状態のコントロール
active という boolean 値でストップウォッチの状態をコントロールします。
Timeline
別スレッドで定期的に何かしらの処理を実行させる仕組みとして、JavaFX には Timeline というクラスが用意されています。今回は下記の通り初期化し、100ms ごとにカウントアップと表示の更新を実施させます。
timeline = new Timeline(
new KeyFrame(Duration.millis(100),
e2 -> {
if (!active) {
return;
}
final Duration duration = ((KeyFrame) e2.getSource()).getTime();
time = time.add(duration);
timeSeconds.set(makeText(time));
}
)
);
表示
Duration は double で値を取得できるので、整数値に調整する必要があります。 今回 floor を使ったのは端数切捨てでないと時計らしい表示にならないためです。 コメントでキャストでよいと指摘を頂きました。@shiracamus さんありがとうございます。
private String makeText(final Duration duration) {
return String.format("%02d:%02d",
(long) (duration.toMinutes() % 60.0),
(long) (duration.toSeconds() % 60.0)
)
+ (active ? "▶" : "■");
}
Button
ストップウォッチ本体だけだと操作に不自由するので、 Button を2つ追加します。
start
そのままです。ストップウォッチの状態によってテキストを変えます。
final Button start = new Button("Start");
start.setOnAction(eve -> {
start.setText(stopwatch.isActive() ? "Start" : "Stop");
stopwatch.start();
});
reset
カウント状況をリセットする Button です。
final Button reset = new Button("Reset");
reset.setOnAction(eve -> {stopwatch.reset();});