2007年12月4日火曜日

JavaFXでアラーム時計を作る(3)

アラーム音再生やメッセージ表示の準備ができたので、JavaFXのプログラムからこれを呼び出せるようにしてみます(以降、いずれもNetBeansで作業を行う場合を例に記述しています)。
作成したアラーム出力Javaアプリケーションプロジェクトの、「〈プロジェクト名〉\build\classes\〈パッケージ名〉\」ディレクトリの下に構築されたクラスファイル(私の場合は、「Sound..class」)と、コピーしておいたサウンドファイル(同様に、「TestMusic.wav」)を、ともに、アラーム時計JavaFXアプリケーションプロジェクトの方の「〈プロジェクト名〉\build\classes\〈パッケージ名〉\」ディレクトリの下にコピーします。
そして、12月2日の投稿で紹介した上記のアラーム時計
JavaFXファイル(同じく「AlarmClock.fx」)に、以下の変更を加えます。
まず、アラーム出力クラスのインポート文を追加します(以下、いずれも私が指定したパッケージ名やファイル名で記述します)。

import timer.Sound;

このとき、「Sound」の下に赤い波線が表示され、「undefined type ...」のエラーアイコンが表示されますが、無視します(エラーメッセージが表示されますが、ちゃんとクラスファイルを認識しています)。
そして、Timer.elapsedの置換triggerアクションの定義に続けて、次のTimer.runningの置換triggerアクションの定義を追加します。

trigger on Timer.running = value {
if (remainingTime <= 0) {Sound.alarm();} }

これで、準備が整いました。最後に、アラーム時計
アプリケーションのプロジェクトを構築しなおして(このとき、「Clean and Build Project」を実行しないように注意します。せっかくコピーしたアラーム出力クラスファイルとサウンドファイルが消されてしまいます)、プロジェクトを実行します。
アラーム時計のウィンドウが表示され、タイマに設定した時間(現在は10秒固定)が経過すると、アラーム音が鳴り、メッセージウィンドウが表示されます。









ここまでくれば、アラームタイマはほとんど完成したも同然です。あとは、タイマの時間を設定できるようにするだけですが、今日はここまで。いつものように、ソースコード全体を載せておきます。

package timer;

import javafx.ui.*;
import javafx.ui.canvas.*;
import java.util.Date;
import java.lang.Math;
import java.lang.System;
import timer.Sound;

public class Timer {
private attribute elapsed: Number;
public attribute seconds: Number;
public attribute minutes: Integer;
public attribute hours: Integer;
public attribute count: Number;
public attribute startTime: Number;
public attribute elapsedTime: Number;
public attribute remainingTime: Number;
public attribute running: Boolean;
}

attribute Timer.elapsed = bind if running
then [1..10] dur 1000 linear while running continue if running
else 0;

trigger on Timer.elapsed = value {
var now = new Date();
elapsedTime = now.getTime() / 1000 - startTime;
remainingTime = count - elapsedTime;
running = if (elapsedTime >= count) then false else true;
seconds = remainingTime % 60;
minutes = ((Integer)remainingTime / 60) % 60;
hours = ((Integer)remainingTime / 60) / 60;
hours = if (elapsedTime >= count) then 0 else hours;
}

trigger on Timer.running = value {
if (remainingTime <= 0) {Sound.alarm();}
}

var date = new Date();

Frame {
var t = Timer {seconds:10, minutes:0, hours:0, count:10,
startTime:(date.getTime() / 1000), running:true}
title: "JavaFX アラーム"
height: 225
width: 215
onClose: operation() {System.exit(0);}
content:
Canvas {
content:
Group {
var font = new Font("Dialog", "PLAIN", 15)
var secs = bind t.seconds
var mins = bind t.minutes + secs / 60
var hrs = bind t.hours + mins / 60
content:
[Rect {
height: 225
width: 225
fill: white
},
Circle {cx: 100, cy: 100, radius: 80, fill: white, stroke: black, strokeWidth: 1},
Group {
transform: translate(100, 100)
content: foreach (i in [1..12])
Text {
var radians = Math.toRadians(30 * i - 90)
transform: [translate((70 * Math.cos(radians)), (70 * Math.sin(radians)))]
content: "{i}"
valign: MIDDLE
halign: CENTER
}
},
Group {
transform: translate(100, 100)
var hourHand =
Line {x1: 0, y1: 0, x2: 0, y2: -35,
strokeWidth: 4, stroke: black
transform: bind rotate((hrs * 30), 0, 0)
}
var minuteHand =
Line {x1: 0, y1: 0, x2: 0, y2: -55,
strokeWidth: 2, stroke: blue,
transform: bind rotate((mins * 6), 0, 0)
}
var secondHand =
Line {x1: 0, y1: 0, x2: 0, y2: -75,
strokeWidth: 1, stroke: red,
transform: bind rotate((t.seconds * 6), 0, 0)
}
content: [hourHand, minuteHand, secondHand]
},
Circle {cx: 100, cy: 100, radius: 3, fill: black, stroke: black }]
},
}
visible: true
}

0 件のコメント: