JAVA时钟

JAVA时钟_第1张图片



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

/**
 * 画我的钟表
 * 
 * @author Eiffel
 * 
 */
public class MyClock extends JFrame {

 MyPanel mp = null;

 public MyClock() {
  // 创建我的面板
  mp = new MyPanel();

  // 添加线程
  Thread t = new Thread(mp);
  t.start();

  // 设置窗体属性
  this.add(mp);
  this.setTitle("时钟");
  this.setBounds(500, 150, 400, 300);
  this.setResizable(false);
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  this.setVisible(true);
 }

 public static void main(String args[]) {

  try {
   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  } catch (Exception e) {
   e.printStackTrace();
  }

  // 启动程序
  new MyClock();

 }
}

class MyPanel extends JPanel implements Runnable {

 Calendar currentTime = null;

 //控制点的大小
 double s = 0.04;

 public MyPanel() {
  // 获取当前时间
  currentTime = Calendar.getInstance();
 }

 @Override
 public void paint(Graphics g) {
  super.paint(g);
  Graphics2D g2d = (Graphics2D) g;
  //画时钟
  drawClock(g2d);
 }

 // 设置当前Calendar
 public void setCurrentTime(Date time) {
  this.currentTime.setTime(time);
 }

 // 设置当前Calendar
 public void setCurrentTime(long millis) {
  this.currentTime.setTimeInMillis(millis);
 }

 // 画出时钟
 private void drawClock(Graphics2D g2d) {

  // 反锯齿开关开,图像变得平滑
  g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);
  Insets insets = getInsets();
  // 宽
  int wid = getWidth() - insets.left - insets.right;
  // 高
  int hei = getHeight() - insets.top - insets.bottom;

  // 定义出最长指针(半径)(去除面板的最小边计算)(画出了最大的时钟)
  //int r = (int) ((Math.min(wid, hei)) / 2 / (1 + s));
  int r = (int) ((Math.min(wid, hei)) / 2/(1+s));

  // 把绘图平移
  g2d.translate(insets.left + r * (1 + s), insets.top + r * (1 + s));
  // 将当前 Graphics2D Transform 与缩放转换连接
  g2d.scale(1, -1);

  // 画出60个点
  for (int i = 0; i < 60; i++) {
   // 角度
   int angel = 90 - i * 6;
   double pos[] = operatPos(r, angel);
   // 画点
   paintDot(r, g2d, pos[0], pos[1], i);
  }
  // 画秒针
  paintSecoundPointer(r, g2d);
  // 画时针
  paintHourPointer(r, g2d);
  // 画分针
  paintMinutePointer(r, g2d);
  // 画中点
  paintCenterPoint(g2d);
  g2d.translate(-insets.left - r * (1 + s), -insets.top - r * (1 + s));
  g2d.scale(1, -1);
 }

 // 画秒针

 private void paintSecoundPointer(double r, Graphics2D g2d) {
  g2d.setColor(Color.BLACK);
  // 获得秒数
  int second = currentTime.get(Calendar.SECOND);
  int angle = 90 - second * 6;
  double pos[] = operatPos(r * 0.9, angle);
  double pos1[] = operatPos(r * 0.2, angle + 180);
  Line2D line = new Line2D.Double(pos1[0], pos1[1], pos[0], pos[1]);
  g2d.draw(line);
  // g2d.drawLine((int)pos1[0], (int)pos1[1], (int)pos[0], (int)pos[1]);

 }

 // 画时针
 private void paintHourPointer(double r, Graphics2D g2d) {
  // 获得小时时间
  int hour = currentTime.get(Calendar.HOUR);
  // 获得分钟时间
  int minute = currentTime.get(Calendar.MINUTE);
  // 获得秒时间
  int second = currentTime.get(Calendar.SECOND);

  // 计算角度(1小时是30度)
  double angle = 90 - (hour + minute / 60.0 + second / 3600.0) * 30;

  // 多边形针(第一个参数确定指针长短,第二个确定指针拐点位置,第三个确定指针尾部的位置)
  Shape pointerShape = createPointerShape(r * 0.6, r * 0.06, r * 0.1,
    angle);
  // double pos[] = operatPos(r, angle);
  // 画时针
  g2d.setColor(Color.LIGHT_GRAY);
  g2d.fill(pointerShape);
  // 画时针边框
  g2d.setColor(Color.DARK_GRAY);
  g2d.draw(pointerShape);

 }

 // 画分针

 private void paintMinutePointer(double r, Graphics2D g2d) {
  // 获得分钟时间
  int minute = currentTime.get(Calendar.MINUTE);
  // 获得秒时间
  int secound = currentTime.get(Calendar.SECOND);

  // 计算弧度
  double angle = 90 - (minute + secound / 60.0) * 6;
  Shape pointerShape = createPointerShape(r * 0.8, r * 0.04, r * 0.08,
    angle);
  g2d.setColor(Color.LIGHT_GRAY);
  g2d.fill(pointerShape);
  g2d.setColor(Color.DARK_GRAY);
  g2d.draw(pointerShape);
 }

 /*
  * 画指针 创建指针路径多变形
  * 
  * @param r1 从圆心到指针定点的长度
  * 
  * @param r2 从圆心到指针侧边端点的距离
  * 
  * @param r3 从圆心到指针尾部端点的距离
  * 
  * @param angle 指针角度
  * 
  * @return
  */
 private Shape createPointerShape(double r1, double r2, double r3,
   double angle) {
  GeneralPath gp = new GeneralPath();
  double[] pos = operatPos(r1, angle);// 指针定点
  double[] pos1 = operatPos(r2, angle + 90);// 指针侧边断点
  gp.append(new Line2D.Double(pos[0], pos[1], pos1[0], pos1[1]), true);
  double[] pos2 = operatPos(r3, angle + 180);// 指针尾部
  gp.lineTo((float) pos2[0], (float) pos2[1]);
  double[] pos3 = operatPos(r2, angle + 270);// 指针的另一侧边断点(上侧)
  gp.lineTo((float) pos3[0], (float) pos3[1]);
  gp.closePath();
  return gp;
 }

 /*
  * 画时钟中间那一点
  * 
  * @param g2d
  */
 private void paintCenterPoint(Graphics2D g2d) {
  g2d.setColor(Color.BLUE);
  // 前两个参数坐标,后两个参数大小
  Rectangle2D rect = new Rectangle2D.Double(-2, -2, 6, 6);
  g2d.fill(rect);
 }

 // 画出60个点
 private void paintDot(int r, Graphics2D g, double x, double y, int i) {
  int flag = 0;
  if (i % 15 == 0) {
   g.setColor(Color.RED);
   flag = 2;
  } else if (i % 5 == 0) {
   g.setColor(Color.GREEN);
   flag = 2;
  } else {
   g.setColor(Color.BLACK);
   flag = 1;
  }

  if (flag == 2) {
   // 第一个Ellipse2D 的窗体矩形左上角的 X 坐标,第二个Ellipse2D 的窗体矩形左上角的 Y 坐标
   // 第三个参数Eclipse2D总高度,第四个参数总宽度,
   // 说简单点 前两个表示坐标,后两个表示大小
   Ellipse2D rect = new Ellipse2D.Double(x - r * s, y - r * s, r * s
     * 2, r * s * 2);
   g.fill(rect);
  } else if (flag == 1) {
   Ellipse2D rect = new Ellipse2D.Double(x - r * 0.02, y - r * 0.02,
     r * 0.04, r * 0.04);
   g.fill(rect);
  }

 }

 // 计算公式(根据半径和弧长计算坐标)
 public double[] operatPos(double r, double angle) {
  // 角度转换成弧度
  // System.out.println("角度是:" + angle);
  double radian = Math.toRadians(angle);
  // System.out.println("弧度是:" + angle);
  double x = r * Math.cos(radian);
  double y = r * Math.sin(radian);

  // 范围数组
  return new double[] { x, y };
 }

 // 执行线程
 @Override
 public void run() {
  while (true) {
   try {
    // 间隔一秒刷新面板
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }

   // 重新得到当前的时间,并设置
   setCurrentTime(System.currentTimeMillis());
   // 重绘
   this.repaint();
  }
 }

}

你可能感兴趣的:(JavaSE,GUI)