JavaのSwingを使った簡単なシンプルなアナログ時計です!
ここではThreadを使っていますがTimerでもいけますね。
スレッドって本当に必要なときでない限り
Javaソースを参考にしたページがあってここにリンクを貼りたいのですが、
いまとなっては見つからず……。
アナログ時計のサンプルも最近けっこうごろごろ転がっていて
なかなかカスタマイズ性の高そうなものもあるんで
検索して調べてみると面白いかもしれません。
ソースコード
package purin; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.util.Calendar; import java.util.GregorianCalendar; import javax.swing.JFrame; import javax.swing.JPanel; public class Clock01 extends JFrame implements Runnable { private static final long serialVersionUID = 1L; Container con; Thread th; static final int sizBase = 200; static final int sizX = sizBase + 10; static final int sizY = sizBase + 40; public Clock01() { setTitle("とけい"); setSize(sizX,sizY); con = getContentPane(); ClockPanel cp = new ClockPanel(); con.add(cp, "Center"); clockStart(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void clockStart() { if ( th == null ) { th = new Thread(this); th.start(); } else th = null; } public void run() { Thread cth = Thread.currentThread(); while ( th == cth ) { repaint(); try { Thread.sleep(1000); } catch(InterruptedException e) { } } repaint(); } public static void main(String[] args) { Clock01 ck01 = new Clock01(); ck01.setVisible(true); } } class ClockPanel extends JPanel { private static final long serialVersionUID = 1L; static final double PI = 3.1416; static final double DegrOf0h = PI / 2.0; // 0時の角度(ラジアン) static final double DegrOf1h = PI / 3.0; // 1時の角度(ラジアン) static final double DegrPerHour = PI / 6.0; // 1時間あたりの角度(ラジアン) static final double DegrPerMin = PI / 30.0; // 1分あたりの角度(ラジアン) static final double DegrPerSec = PI / 30.0; // 1秒あたりの角度(ラジアン) static final int ClockBaseSize = 180; // 時計基準サイズ static final int RadiusOfFont = ClockBaseSize / 2 - 15; // フォントの半径 static final int SecHandLen = 80; static final int MinHandLen = 70; static final int HourHandLen = 60; double s,m,h; int centerX, centerY; double sAng,mAng,hAng; Font ft; private class Point { // InnerClass 無理やり構造体…こんな使い方いいの? int[] px; int[] py; Point() { px = new int[4]; py = new int[4]; } } public ClockPanel() { ft = new Font("SansSerif",Font.BOLD,24); centerX = 100; centerY = 100; } public void paintComponent(Graphics g) { super.paintComponent(g); g.setFont(ft); g.setColor(Color.white); g.fillOval(10,10,180,180); g.setColor(Color.black); double theta = DegrOf1h; FontMetrics fm = g.getFontMetrics(ft); int numH = fm.getHeight()/2; for ( int i=1; i<=12; i++ ) { String num = Integer.toString(i); int x = centerX + (int)(Math.cos(theta) * RadiusOfFont); int y = centerY - (int)(Math.sin(theta) * RadiusOfFont); int numW = fm.stringWidth(num); g.drawString(num, x - numW / 2, y + numH / 2); theta = theta - DegrPerHour; } GregorianCalendar cal = new GregorianCalendar(); s = (double)(cal.get(Calendar.SECOND)); m = (double)(cal.get(Calendar.MINUTE)) + s / 60.0; h = (double)(cal.get(Calendar.HOUR)) + m / 60.0; // 針の位置を示す角度の計算 sAng = DegrOf0h - DegrPerSec * s; mAng = DegrOf0h - DegrPerMin * m; hAng = DegrOf0h - DegrPerHour * h; Point[] pt = new Point[3]; pt[0] = createClockHand(SecHandLen, centerX, centerY, sAng, PI / 24.0); pt[1] = createClockHand(MinHandLen, centerX, centerY, mAng, PI / 20.0); pt[2] = createClockHand(HourHandLen, centerX, centerY, hAng, PI / 16.0); // 秒・分・時針を描く g.setColor(Color.magenta); g.fillPolygon(pt[0].px, pt[0].py, 4); g.setColor(Color.blue); g.fillPolygon(pt[1].px, pt[1].py, 4); g.fillPolygon(pt[2].px, pt[2].py, 4); } private Point createClockHand(int typeLen, int centerX, int centerY, double angle1, double angle2 ) { final int Len = 20; Point pt = new Point(); // 中心のx,y座標 pt.px[0] = centerX; pt.py[0] = centerY; // 時計の中心と針の先端以外の二つの頂点の座標(右) pt.px[1] = centerX + (int)(Len * Math.cos(angle1 + angle2)); pt.py[1] = centerY - (int)(Len * Math.sin(angle1 + angle2)); // (時or分or秒)針の先端のx,y座標 pt.px[2] = centerX + (int)(typeLen * Math.cos(angle1)); pt.py[2] = centerY - (int)(typeLen * Math.sin(angle1)); // 時計の中心と針の先端以外の二つの頂点の座標(左) pt.px[3] = centerX + (int)(Len * Math.cos(angle1 - angle2)); pt.py[3] = centerY - (int)(Len * Math.sin(angle1 - angle2)); return pt; } }
関連リンク
C++でのDirect2D + WIC + Windows APIでアナログ時計はこちら
C++でのシンプル実装はこちら