JAVAでアナログ時計を描く

1.ファイル名:MainFrame.java
コード下記
package com.zengjie.graphics.watch;

import java.awt.Point;

import javax.swing.JFrame;

public class MainFrame extends JFrame
{

public static void main(String[] args)
{
MainFrame frame = new MainFrame();
frame.setSize(400, 400);
Watch watch = new Watch(200);
watch.setLocation(new Point(0, 0));
frame.add(watch);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

2.

ファイル名:Watch.java
サンプルコード下記:

package com.zengjie.graphics.watch;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.Date;

import javax.swing.JComponent;
import javax.swing.SwingUtilities;

public class Watch extends JComponent
{

private static final int BORD_SIZE = 4;

private Date timeToDraw;

private Timmer timmer;

public Watch()
{
this.timeToDraw = new Date();
this.timmer = new Timmer();
timmer.start();
}

public Watch(int size)
{
this();
this.setSize(size, size);
}

@Override
public void setSize(int width, int height)
{
int size = Math.min(width, height);
super.setSize(size, size);
}

@Override
public void paint(Graphics g)
{
// super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int size = Math.min(getWidth(), getHeight());
g2d.drawImage(getBufferedImage(size), 0, 0, new Color(255, 255, 255,
255), null);
// drawBase(g2d, size);
// g2d.drawString(timeToDraw.toString(), 40, 40);
drawHour(g2d, timeToDraw);
drawMins(g2d, timeToDraw);
drawSeconds(g2d, timeToDraw);

// 最後中央にドットを描画
double baseR = (double) size / 2;
int point = (int) (baseR * 0.96);
int pointR = (int) (baseR * 0.08);
g2d.fillArc(point, point, pointR, pointR, 0, 360);
}

private void drawBase(Graphics2D g2d, int size)
{
g2d.clearRect(0, 0, getWidth(), getHeight());

int center = size / 2;// 原点
// ブラックシャーシ
g2d.setColor(Color.black);
g2d.fillArc(0, 0, size, size, 0, 360);

// グレーのベゼル
g2d.setColor(Color.gray);
g2d.setStroke(new BasicStroke(BORD_SIZE));
g2d.drawArc(0, 0, size, size, 0, 360);

// 白いスケール
g2d.setColor(Color.WHITE);
g2d.setStroke(new BasicStroke(2));
Point start = new Point();
Point end = new Point();

int rstart = (int) ((double) center * 0.95);
int rSpec = (int) ((double) center * 0.92);

for (int i = 0; i < 360; i += 6)
{
if (i % 30 == 0)
{
g2d.setStroke(new BasicStroke(3));
caculateLinePos(center, start, i, rSpec);
}
else
{
g2d.setStroke(new BasicStroke(2));
caculateLinePos(center, start, i, rstart);
}
caculateLinePos(center, end, i, center – 2);
g2d.drawLine(start.x, start.y, end.x, end.y);
}
}

private void drawSeconds(Graphics2D g2d, Date date)
{
g2d.setColor(Color.RED);
// g2d.setStroke(new BasicStroke(2));
int size = Math.min(getWidth(), getHeight());
int center = size / 2;// 原点
double r = (float) center * 0.8;

int seconds = date.getSeconds();
double angle = (float) seconds / 60 * 360;
int mills = (int) (date.getTime() % 1000);
angle += (6 * ((float) mills / 1000));

drawLine(g2d, angle, center, r, 0.15f, 2);
}

private void drawMins(Graphics2D g2d, Date d)
{
g2d.setColor(Color.GRAY);
// g2d.setStroke(new BasicStroke(4));
int size = Math.min(getWidth(), getHeight());
int center = size / 2;// 原点
double r = (float) center * 7 / 10;
int min = d.getMinutes() + 1;
double angle = (float) min / 60 * 360;
int sec = d.getSeconds();
angle += (6 * ((float) sec / 60));
drawLine(g2d, angle, center, r, 0.12f, 4);
}

private void drawHour(Graphics2D g2d, Date d)
{
g2d.setColor(Color.WHITE);
// g2d.setStroke(new BasicStroke(6));
int size = Math.min(getWidth(), getHeight());
int center = size / 2;// 原点
double r = (double) center * 6 / 10;
int hour = d.getHours() + 1;
double angle = (double) hour / 24 * 360;
int mins = d.getMinutes() + 1;
angle += (360 / 24) * (mins / 60);
// int mills = (int) (d.getTime() % (60 * 1000));
// arc += (6 * ((float) mills / 1000));
drawLine(g2d, angle, center, r, 0.1f, 6);
}

// private void drawLine(Graphics2D g2d, int angle, int center, int r,
// float outPer)
// {
// drawLine(g2d, angle, center, r);
// drawLine(g2d, (angle + 180) % 360, center, (int) (r * outPer));
// }

private BufferedImage baseImage;

/**
* 画像バッファをダイヤル
*
* @param size
* @return
*/
private BufferedImage getBufferedImage(int size)
{
if (baseImage == null)
{
baseImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = baseImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setBackground(new Color(255, 255, 255, 255));
g2d.clearRect(0, 0, baseImage.getWidth(), baseImage.getHeight());
drawBase(g2d, size);
g2d.dispose();
}
return baseImage;

}

private Point hourEnd;

@Override
public void repaint()
{
baseImage = null;
super.repaint();
}

private void drawLine(Graphics2D g2d, double angle, int center, double r,
float out, int lineWidth)
{
g2d.setStroke(new BasicStroke(lineWidth));
// Point start = new Point(center, center);
Point end = new Point();
caculateLinePos(center, end, angle, r);

Point start = new Point();

double outAngle = (angle + 180) % 360;
double outR = out * r;
caculateLinePos(center, start, outAngle, outR);

g2d.drawLine(start.x, start.y, end.x, end.y);
// y=ax+b
// double a, b = 0;
// start.y = start.x * a + b;
// b = start.y – start.x * ((end.y – b) / end.x);
// b = start.y – start.x * end.y / end.y – start.x * b / end.y;
// b*end.y = start.y*end.y-start.x*end.y -b;
// b = ((double) start.y * end.y – start.x * end.y) / (1 + end.y);
// a = ((double) start.y – b) / start.x;
// System.out.println(a + “\t" + b);
}

private void caculateLinePos(int center, Point end, double angle, double r)
{
// int center = start.x;
// Point start = new Point(center, center);
// Point end = new Point();
// System.out.println(seconds);
double arc = angle % 90 / 180 * Math.PI;
if (angle == 0d || angle == 360d)
{
end.setLocation(center, center – r);
}
else if (angle == 90d)
{
end.setLocation(center + r, center);
}
else if (angle == 180d)
{
end.setLocation(center, center + r);
}
else if (angle == 270d)
{
end.setLocation(center – r, center);
}
else if (angle > 0 && angle < 90)
{
int x = (int) (r * Math.sin(arc));
int y = (int) (r * Math.cos(arc));
// System.out.println(Math.cos(90 – arc) + “\t" + Math.sin(90 –
// arc));
// System.out.println(x + “\t" + y + “\t" + r);
// System.out.print(Math.pow(x, 2) + “\t");
// System.out.print(Math.pow(y, 2) + “\t");
// System.out.println(Math.pow(r, 2));
end.setLocation(x + center, center – y);
// System.out.println();
}
else if (angle > 90 && angle < 180)
{
// angle = angle – 90;
int x = (int) (r * Math.cos(arc));
int y = (int) (r * Math.sin(arc));
end.setLocation(x + center, center + y);
}
else if (angle > 180 && angle < 270)
{
// angle = angle – 180;
int x = (int) (r * Math.sin(arc));
int y = (int) (r * Math.cos(arc));
end.setLocation(center – x, center + y);
}
else if (angle > 270 && angle < 360)
{
// angle = angle – 270;
int x = (int) (r * Math.cos(arc));
int y = (int) (r * Math.sin(arc));
end.setLocation(center – x, center – y);
}
}

// public static void main(String[] args)
// {
// System.out.println(Math.sin(Math.PI / 2 / 3));
// }

private class Timmer extends Thread
{

@Override
public void run()
{
while (true)
{
long time = System.currentTimeMillis();
if (time % 1000 == 0)
{
final Date now = new Date(time);
SwingUtilities.invokeLater(new Runnable()
{

public void run()
{
Watch.this.timeToDraw = now;
Watch.this.paint(Watch.this.getGraphics());
}
});
try
{
Thread.currentThread().sleep(950);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

}

Source

Posted by arkgame