/**********************************************************************************
* *
* 音の出る時計Javaアプレット *
* ( SoundClock.java ) *
* *
* Author : Seiichi Inoue *
**********************************************************************************/
/****************** << インポートパッケージクラス定義 >> ********************/
import java.applet.Applet; /* Appletパッケージ */
import java.awt.*; /* Abstract Windowing Toolkitパッケージの全て*/
import java.util.Date; /* Dateパッケージ */
import java.applet.AudioClip; /* AudioClipパッケージ */
/************************ << 自分のクラス定義 >> ****************************/
// クラス名称 : SoundClock
// アクセス制御 : public(どのクラスからもアクセス可能)
// 継承クラス : Applet
// 引継クラス : Runnable(Threadを使用可能にする)
public class SoundClock extends Applet implements Runnable {
/************************ << クラス属性の定義 >> ****************************/
Dimension dm; /* 表示領域 */
Thread kicker=null; /* スレッド制御(初期値:停止) */
Image offs; /* オフスクリーンエリア */
Graphics grf; /* 描画領域 */
Image img; /* 背景イメージ情報 */
MediaTracker mt; /* メディアトラッカー */
String param; /* 入力パラメータ取込エリア */
int imgsw; /* 背景イメージ有無情報 */
int h_fontsize; /* 時表示フォント情報 */
int m_fontsize; /* 分表示フォント情報 */
int s_fontsize; /* 秒表示フォント情報 */
String sh,h10,h01; /* 時表示文字情報 */
String sm,m10,m01; /* 分表示文字情報 */
String ss,s10,s01; /* 秒表示文字情報 */
int h10x,h10y,h01x,h01y; /* 時表示位置情報 */
int m10x,m10y,m01x,m01y; /* 分表示位置情報 */
int s10x,s10y,s01x,s01y; /* 秒表示位置情報 */
int am_pm; /* 午前/午後情報 */
int cent_x,cent_y; /* アナログ時計中心座標 */
boolean digital,analog; /* 表示/非表示情報 */
int r; /* アナログ時計のサイズ情報 */
AudioClip sound = null; /* 時報音情報 */
boolean sound_sw; /* 時報有無情報 */
boolean played = false; /* 時報起動済情報(初期値:未起動)*/
Color backcolor; /* 背景色情報 */
/******************** << クラスのメッソード指定(実行手順) >> **************/
/*********** 初期化(init)メッソード **********/
public void init() {
dm = size(); /* 表示画面サイズ情報を設定 */
offs = createImage(dm.width,dm.height); /* オフスクリーン用エリア作成 */
grf = offs.getGraphics(); /* Graphicsオブジェクト取出 */
param = getParameter("image"); /* 背景イメージ入力取込 */
if ( param != null ) { /* 入力パラメータ有り? */
mt = new MediaTracker(this); /* メディアトラッカーインスタンス */
img = getImage(getCodeBase(),param);/* 背景イメージ取込 */
mt.addImage(img,0); /* イメージロード監視登録 */
imgsw = 1; /* 背景イメージ有り情報設定 */
}
else { /* NO :入力指定無し */
imgsw = 0; /* 背景イメージ無し情報設定 */
param = getParameter("backred"); /* 背景赤色パラメータ取込 */
int backred = (param != null)? /* 入力判定(無指定時:0) */
Integer.parseInt(param): 0;
param = getParameter("backgreen"); /* 背景緑色パラメータ取込 */
int backgreen = (param != null)? /* 入力判定(無指定時:0) */
Integer.parseInt(param): 0;
param = getParameter("backblue"); /* 背景青色パラメータ取込 */
int backblue = (param != null)? /* 入力判定(無指定時:0) */
Integer.parseInt(param): 0;
backcolor = new Color /* 背景色組立 */
(backred,backgreen,backblue);
}
param = getParameter("h_fontsize"); /* 時間表示フォントサイズ入力取込 */
h_fontsize = (param != null)? /* 入力判定(無指定時:20ポイント) */
Integer.parseInt(param): 20;
param = getParameter("m_fontsize"); /* 分表示フォントサイズ入力取込 */
m_fontsize = (param != null)? /* 入力判定(無指定時:20ポイント) */
Integer.parseInt(param): 20;
param = getParameter("s_fontsize"); /* 秒表示フォントサイズ入力取込 */
s_fontsize = (param != null)? /* 入力判定(無指定時:20ポイント) */
Integer.parseInt(param): 20;
param = getParameter("h10x"); /* 時10位表示位置(横)入力取込 */
h10x = (param != null)? /* 入力判定(無指定時:0) */
Integer.parseInt(param): 0;
param = getParameter("h10y"); /* 時10位表示位置(縦)入力取込 */
h10y = (param != null)? /* 入力判定(無指定時:20) */
Integer.parseInt(param): 20;
param = getParameter("h01x"); /* 時1位表示位置(横)入力取込 */
h01x = (param != null)? /* 入力判定(無指定時:10) */
Integer.parseInt(param): 10;
param = getParameter("h01y"); /* 時1位表示位置(縦)入力取込 */
h01y = (param != null)? /* 入力判定(無指定時:20) */
Integer.parseInt(param): 20;
param = getParameter("m10x"); /* 分10位表示位置(横)入力取込 */
m10x = (param != null)? /* 入力判定(無指定時:30) */
Integer.parseInt(param): 30;
param = getParameter("m10y"); /* 分10位表示位置(縦)入力取込 */
m10y = (param != null)? /* 入力判定(無指定時:20) */
Integer.parseInt(param): 20;
param = getParameter("m01x"); /* 分1位表示位置(横)入力取込 */
m01x = (param != null)? /* 入力判定(無指定時:40) */
Integer.parseInt(param): 40;
param = getParameter("m01y"); /* 分1位表示位置(縦)入力取込 */
m01y = (param != null)? /* 入力判定(無指定時:20) */
Integer.parseInt(param): 20;
param = getParameter("s10x"); /* 秒10位表示位置(横)入力取込 */
s10x = (param != null)? /* 入力判定(無指定時:60) */
Integer.parseInt(param): 60;
param = getParameter("s10y"); /* 秒10位表示位置(縦)入力取込 */
s10y = (param != null)? /* 入力判定(無指定時:20) */
Integer.parseInt(param): 20;
param = getParameter("s01x"); /* 秒1位表示位置(横)入力取込 */
s01x = (param != null)? /* 入力判定(無指定時:70) */
Integer.parseInt(param): 70;
param = getParameter("s01y"); /* 秒1位表示位置(縦)入力取込 */
s01y = (param != null)? /* 入力判定(無指定時:20) */
Integer.parseInt(param): 20;
param = getParameter("clock_x"); /* アナログ時計中心X座標取込 */
cent_x = (param != null)? /* 入力判定(無指定時:描画領域中央)*/
Integer.parseInt(param): dm.width/2;
param = getParameter("clock_y"); /* アナログ時計中心Y座標取込 */
cent_y = (param != null)? /* 入力判定(無指定時:描画領域中央)*/
Integer.parseInt(param): dm.height/2;
param = getParameter("digital"); /* デジタル時計表示指定取込 */
param = (param != null)? /* 入力判定(無指定時:true) */
param: "true";
if ( "true".equals (param) ) /* デジタル時計を表示する? */
digital = true; /* YES:表示する(正)設定 */
else
digital = false; /* NO :表示しない(偽)設定 */
param = getParameter("analog"); /* アナログ時計表示指定取込 */
param = (param != null)? /* 入力判定(無指定時:true) */
param: "true";
if ( "true".equals (param) ) /* アナログ時計を表示する? */
analog = true; /* YES:表示する(正)設定 */
else
analog = false; /* NO :表示しない(偽)設定 */
param = getParameter("size"); /* アナログ時計サイズ取込 */
r = (param != null)? /* 入力判定(無指定時:半径60ピクセル) */
Integer.parseInt(param): 60;
param = getParameter("sound"); /* 時報音源取込 */
if ( param == null ) { /* 音源なし? */
sound_sw = false; /* なし(時報なし設定) */
}
else { /* あり */
sound_sw = true; /* (時報あり設定) */
sound = getAudioClip(getCodeBase(),param); /* 時報音取込 */
}
} /* 初期化メソッド終了 */
/********** スタート(start)メソッド **********/
public void start() {
if ( kicker == null ) { /* kickerがnull?(停止中?) */
kicker = new Thread(this); /* YES:kickerを動作中に設定 */
kicker.start(); /* startを設定 */
}
repaint();
} /* スタートメソッド終了 */
/*********** 繰り返し(run)メソッド ***********/
public void run() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3);
if ( imgsw != 0 ) { /* イメージ指定あり? */
try { /* 割り込み確認 */
mt.waitForID(0); /* イメージロード待ち合わせ */
} catch( InterruptedException e ) { /* 割り込み処理 */
System.out.println("Wait Error");
return;
}
}
while( kicker != null) { /* kickerがnullになるまで繰り返し */
repaint(); /* 描画 */
try { /* 割り込み確認 */
kicker.sleep(100); /* 待ち時間を100ミリ秒設定 */
} catch (InterruptedException e) {} /* 割り込み処理 */
}
kicker = null;
} /* 実行メソッド終了 */
/************ 更新(update)メソッド ***********/
public void update(Graphics g) { /* 画面のちらつきを無くす */
paint(g); /* 描画 */
} /* 更新メソッド終了 */
/************ 描画(paint)メソッド ************/
public void paint(Graphics g) {
if ( imgsw != 0 ) { /* 背景イメージ情報有り? */
if ( mt.isErrorID(0)) { /* ロードエラー? */
g.drawString("Image Load Error....",50,20); /* エラー表示 */
return;
}
if( ! mt.checkID(0)) { /* ロード中? */
g.drawString("Loading....",dm.width/2-30,20); /* ロード中表示 */
return;
}
grf.drawImage(img,0,0,this); /* イメージ情報設定 */
}
else { /* NO : */
grf.setColor(backcolor); /* 背景色設定 */
grf.fillRect(0,0,dm.width,dm.height); /* 背景色塗りつぶし */
}
Date d = new Date(); /* 時計情報を取込 */
double h = d.getHours(); /* 時情報を取込 */
double m = d.getMinutes(); /* 分情報を取込 */
double s = d.getSeconds(); /* 秒情報を取込 */
if ( sound_sw ) { /* 時報音源ファイルあり? */
if ( s == 0 ) { /* 0秒? */
if ( played ) {} /* 時報起動済み? */
else { /* 未起動 */
sound.play(); /* 時報を鳴らす */
played = true; /* 起動済み設定 */
}
}
else played = false; /* 0秒以外で未起動情報設定 */
}
// <<デジタル時計描画処理>>
if ( digital ) { /* デジタル時計を表示する? */
/* YES */
if ( h < 12 ) /* 午前? */
am_pm = 0; /* YES:午前情報設定 */
else { /* NO :午後 */
h -= 12; /* 時情報から12時間減算 */
am_pm = 1; /* 午後情報設定 */
}
if ( h < 10 ) /* 1桁( 0 - 9 )? */
sh = " " + h + " "; /* 2桁( 0 - 9 ) + 空白 */
else
sh = h + " "; /* 数字 + 空白(抽出処理のため) */
h10 = sh.substring(0,1); /* 時10位数字抽出 */
h01 = sh.substring(1,2); /* 時1位数字抽出 */
if ( am_pm == 0 ) /* 午前? */
grf.setColor(Color.red); /* 午前文字色(赤)設定 */
else
grf.setColor(Color.green); /* 午後文字色(緑)設定 */
grf.setFont(new Font("Dialog",Font.BOLD,h_fontsize)); /* フォント情報設定 */
grf.drawString( h10, h10x, h10y ); /* 時10位表示情報設定 */
grf.drawString( h01, h01x, h01y ); /* 時1位表示情報設定 */
if ( m < 10 ) /* 1桁( 0 - 9 )? */
sm = "0" + m + " "; /* 2桁( 00 - 09 ) + 空白 */
else
sm = m + " "; /* 数字 + 空白(抽出処理のため) */
m10 = sm.substring(0,1); /* 分10位数字抽出 */
m01 = sm.substring(1,2); /* 分1位数字抽出 */
if ( am_pm == 0 ) /* 午前? */
grf.setColor(Color.red); /* 午前文字色(赤)設定 */
else
grf.setColor(Color.green); /* 午後文字色(緑)設定 */
grf.setFont(new Font("Dialog",Font.BOLD,m_fontsize)); /* フォント情報設定 */
grf.drawString( m10, m10x, m10y ); /* 分10位表示情報設定 */
grf.drawString( m01, m01x, m01y ); /* 分1位表示情報設定 */
if ( s < 10 ) /* 1桁( 0 - 9 )? */
ss = "0" + s + " "; /* 2桁( 00 - 09 ) + 空白 */
else
ss = s + " "; /* 数字 + 空白(抽出処理のため) */
s10 = ss.substring(0,1); /* 秒10位数字抽出 */
s01 = ss.substring(1,2); /* 秒1位数字抽出 */
grf.setColor(Color.red); /* 文字色設定 */
grf.setFont(new Font("Dialog",Font.BOLD,s_fontsize)); /* フォント情報設定 */
grf.drawString( s10, s10x, s10y ); /* 秒10位表示情報設定 */
grf.drawString( s01, s01x, s01y ); /* 秒1位表示情報設定 */
}
// <<アナログ時計描画処理>>
if ( analog ) { /* アナログ時計を表示する? */
/* YES */
double rd = 3.14159/180; /* ラジアン値(64bit) */
grf.setColor(Color.yellow); /* 文字盤色設定 */
for ( int k=0; k<60; k++ ) { /* 文字盤(60ドット)描画 */
int dmx = (int)(cent_x+(r+5)*Math.sin(k*6*rd)); /* X座標計算 */
int dmy = (int)(cent_y+(r+5)*Math.cos(k*6*rd)); /* Y座標計算 */
grf.fillOval(dmx-1,dmy-1,2,2); /* 2ピクセルの丸を描画 */
}
grf.setColor(Color.red); /* 5分用ドット色設定 */
for ( int k=0; k<12; k++ ) { /* 文字盤(12ドット)描画 */
int dx = (int)(cent_x+(r+5)*Math.sin(k*30*rd)); /* X座標計算 */
int dy = (int)(cent_y-(r+5)*Math.cos(k*30*rd)); /* Y座標計算 */
grf.fillRect(dx-3,dy-3,6,6); /*6ピクセルの四角を描画 */
}
// 時針、分針の幅座標を求める式で最後の項(0.5とか0.4)は中心からの角度です。
// 時計のサイズを変更しても変化しませんので、見栄により変えた方が良いかも知れません。
/* 時針(短針)の処理 */
int hx2 = (int)(cent_x+r/3*Math.sin((h*5+m/12)*6*rd-0.5));/*時針左幅X座標*/
int hy2 = (int)(cent_y-r/3*Math.cos((h*5+m/12)*6*rd-0.5));/*時針左幅Y座標*/
int hx3 = (int)(cent_x+r*2/3*Math.sin((h*5+m/12)*6*rd)); /*時針先端X座標*/
int hy3 = (int)(cent_y-r*2/3*Math.cos((h*5+m/12)*6*rd)); /*時針先端Y座標*/
int hx4 = (int)(cent_x+r/3*Math.sin((h*5+m/12)*6*rd+0.5));/*時針右幅X座標*/
int hy4 = (int)(cent_y-r/3*Math.cos((h*5+m/12)*6*rd+0.5));/*時針右幅Y座標*/
int hxPoint[] = {cent_x,hx2,hx3,hx4}; /* 多角形(ポリゴン)X座標設定 */
int hyPoint[] = {cent_y,hy2,hy3,hy4}; /* 多角形(ポリゴン)Y座標設定 */
grf.setColor(Color.green); /* 時針色設定 */
grf.fillPolygon(hxPoint,hyPoint,4); /* 時針多角形(ポリゴン)描画 */
/* 分針(長針)の処理 */
int mx2 = (int)(cent_x+r/3*Math.sin((m+s/60)*6*rd-0.4)); /*分針左幅X座標*/
int my2 = (int)(cent_y-r/3*Math.cos((m+s/60)*6*rd-0.4)); /*分針左幅Y座標*/
int mx3 = (int)(cent_x+r*Math.sin((m+s/60)*6*rd)); /*分針先端X座標*/
int my3 = (int)(cent_y-r*Math.cos((m+s/60)*6*rd)); /*分針先端Y座標*/
int mx4 = (int)(cent_x+r/3*Math.sin((m+s/60)*6*rd+0.4)); /*分針右幅X座標*/
int my4 = (int)(cent_y-r/3*Math.cos((m+s/60)*6*rd+0.4)); /*分針右幅Y座標*/
int mxPoint[] = {cent_x,mx2,mx3,mx4}; /* 多角形(ポリゴン)X座標設定 */
int myPoint[] = {cent_y,my2,my3,my4}; /* 多角形(ポリゴン)Y座標設定 */
grf.setColor(Color.blue); /* 分針色設定 */
grf.fillPolygon(mxPoint,myPoint,4); /* 分針多角形(ポリゴン)描画 */
/* 秒針の処理 */
int sx2 = (int)(cent_x+r*Math.sin(s*6*rd)); /* 秒針先端X座標 */
int sy2 = (int)(cent_y-r*Math.cos(s*6*rd)); /* 秒針先端Y座標 */
grf.setColor(Color.red); /* 秒針色設定 */
grf.drawLine(cent_x,cent_y,sx2,sy2); /* 秒針描画 */
grf.setColor(Color.red); /* センターノブ色設定 */
grf.fillOval(cent_x-5,cent_y-5,10,10); /* 10ピクセルの円を描画 */
}
g.drawImage(offs,0,0,this); /* 描画設定 */
} /* 描画メソッド終了 */
/********** ストップ(stop)メソッド *********/
public void stop() {
if( kicker != null ) { /* kickerがnullでない?(動作中?) */
kicker.stop(); /* kickerを停止に設定 */
kicker = null; /* kickerに停止状態を設定 */
}
} /* ストップメソッド終了 */
} /* クラス設定終了 */
/**********************************************************************************
* 音の出る時計アプレット終了 *
**********************************************************************************/