| アナログ時計を作ってみました。時計の針を描画するには,針の先端のxy座標を計算しなければなりません。これがやっかいです。 参考書籍などで,数学関数のsin,cosや,ラジアン値を参考にして下さい。 |
import java.applet.*;
import java.awt.*;
import java.util.*; //Dateクラスが属する
public class ja03b extends Applet implements Runnable
{
int w,h; //時計を描画する領域の幅と高さ
int centerX,centerY; //時計の中心座標
int r; //時計の針が動く円形領域の半径
Date nowtime; //現在時刻を格納
Thread td; //スレッド
FontMetrics fm; //フォントメトリックス
Font f;
public void init(){
w = size().width; //Appletのサイズを取得
h = size().height;
if(w<h)h = w; //Appletの幅と高さが異なる場合,時計の描画領域の幅と高さを同じにする
else w = h;
centerX = w/2; //時計の中心座標を求める。
centerY = h/2;
r = (w/2) * 4 / 5; //時計の針が動く円形領域の半径を4/5に小さくする。
nowtime = new Date(); //現在時刻を取得
f = new Font("TimesRoman",Font.BOLD,w/8); //フォントを設定
}
public void start(){
if(td == null){
td = new Thread(this);
td.start();
}
}
public void stop(){
td.stop();
td = null;
}
public void run(){
while(td != null){
repaint();
try{
Thread.sleep(1000); //1秒間隔でスレッドを実行
}catch(InterruptedException e){}
}
}
public void paint(Graphics g){
g.setColor(Color.black);
g.fillRect(0,0,w,h); //時計表示領域全体を黒色で塗り潰す
g.setColor(Color.lightGray);
g.fillOval(0,0,w,h); //薄灰色で塗り潰された円を描く
g.setColor(Color.blue); //時計の数字を描画するための,色,フォント,フォントメトリックス
g.setFont(f);
fm =g.getFontMetrics();
for(int i = 1;i <= 12; i++){ //1〜12の数字を描画
String st = "" + i;
int stw = fm.stringWidth(st); //描画する数字の幅
int sth = fm.getAscent(); //描画する数字の高さ
int stx = (int)(centerX +(w/2 -8) * Math.sin(2 * Math.PI * i/12) - stw/2);
int sty = (int)(centerY -(w/2 -8) * Math.cos(2 * Math.PI * i/12) + sth/2);
//(w/2-8)は,数字を描画する円領域の半径(時計全体の円より8ピクセルだけ小さくする)
//(2 * Math.PI * i/12)は,数字を描画する位置のラジアン値を計算
//-stw/2,+sth/2は,数字の描画位置の調整
g.drawString(st,stx,sty);
}
}
public void update(Graphics g){
g.setColor(Color.pink);
g.fillOval(centerX - r,centerY - r,2*r,2*r); //時計の針が動く円形領域をピンク色で塗り潰す
nowtime = new Date(); //現在時刻を取得
int h = nowtime.getHours(); //現在時刻から,時間,分,秒を取得
int m = nowtime.getMinutes();
int s = nowtime.getSeconds();
g.setColor(Color.black);
double hra = 2 * Math.PI * (h + m/60.0) / 12.0; //現在時間のラジアン値を計算
int hx = (int)(centerX + r*0.5 * Math.sin(hra)); //時針の先端のx座標(長さを半径rの半分に)
int hy = (int)(centerY - r*0.5 * Math.cos(hra)); //同じくy座標を計算
g.drawLine(centerX,centerY,hx,hy); //時針を描画
double mra = 2 * Math.PI * (m + s/60.0) / 60.0; //現在の分のラジアン値を計算
int mx = (int)(centerX + r*0.8 * Math.sin(mra)); //分針の先端のx座標(長さを半径rの0.8倍に)
int my = (int)(centerY - r*0.8 * Math.cos(mra)); //同じくy座標を計算
g.drawLine(centerX,centerY,mx,my); //分針を描画
g.setColor(Color.red);
double sra = 2 * Math.PI * s / 60.0; //秒針のラジアン値を計算
int sx = (int)(centerX + r*0.9 * Math.sin(sra));
int sy = (int)(centerY - r*0.9 * Math.cos(sra));
g.drawLine(centerX,centerY,sx,sy);
}
}
末尾