这两天用Java写了一个小程序,一个会自动走的闹钟。
下面说一下具体的思路,有错误的也有正确的。
错误的思路:
1)以0点0分0秒线为基准,提取系统时间,让时针分针秒针转动相应的角度,得出真正的时间。
延迟一秒,然后让秒针自增6°,循环每60次,让分针再转动6°,时针同理
错误分析:由于在java中画线方法原型是void drawLine(x1,y1,x2,y2),所以无法去引用之前画好的线,并且也没有让画出的某一条线顺时针转动多少度的方法。
所以上面的思路失败。
正确的思路:
以秒针的计算为例:
1)以0秒为基准计算出秒针转过的角度θ=second*(2*PI/60)
2)xEnd=xCenter+sLength*sinθ // sLength是秒针的长度
yEnd=yCenter-sLength*cosθ
3)根据得出坐标,就可以用drawLine(x1,y1,x2,y2)方法画出秒针
让时钟指针运动的原理:
根据系统时间的变化,提取系统时间,然后重画时钟。而不是再想办法让指针真的去转动。
下面贴代码:
import javax.swing.*;
import java.awt.event.*;
public class DisplayClock extends JFrame{
public static void main(String[] args) {
// TODO 自动生成的方法存根
Thread thread=new Thread();
DisplayClock frame=new DisplayClock();
StillClock2 clock=new StillClock2();
frame.add(clock);
frame.setTitle("DisplayClock");
frame.setLocationRelativeTo(null);
frame.setSize(300,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
for(int i=10000;i>0;i--)
{
try {
thread.sleep(1000);
clock.setCurrentTime();
clock.repaint();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
import java.awt.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.JPanel;
public class StillClock extends JPanel {
private int hour;
private int minute;
private int second;
public StillClock(){
setCurrentTime();
}
public StillClock(int hour,int minute,int second){
this.hour=hour;
this.minute=minute;
this.second=second;
}
//override JComtent paintComponent
// g就相当于一个画笔,可以设置颜色
protected void paintComponent(Graphics g){
super.paintComponent(g);
//Initialize clock parameters
int clockRadius=
(int)(Math.min(getWidth(), getHeight())*0.8*0.5);
int xCenter=getWidth()/2;
int yCenter=getHeight()/2;
//Draw circle
g.setColor(Color.black);
g.drawOval(xCenter-clockRadius, yCenter-clockRadius, 2*clockRadius, 2*clockRadius);
g.drawString("12", xCenter-7, yCenter-clockRadius+12);
g.drawString("3", xCenter+clockRadius-12, yCenter-5);
g.drawString("6", xCenter-5, yCenter+clockRadius-5);
g.drawString("9", xCenter-clockRadius+5, yCenter-5);
//Draw second hand
int sLength=(int)(clockRadius*0.8);
int xSecond=(int)(xCenter+sLength*Math.sin(second*(Math.PI*2/60)));
int ySecond=(int)(yCenter-sLength*Math.cos(second*(Math.PI*2/60)));
g.setColor(Color.red);
g.drawLine(xCenter, yCenter, xSecond, ySecond);
//Draw minute hand
int mLength=(int)(clockRadius*0.65);
int xMinute=(int)(xCenter+mLength*Math.sin(minute*(Math.PI*2/60)));
int yMinute=(int)(yCenter-mLength*Math.cos(minute*(Math.PI*2/60)));
g.setColor(Color.blue);
g.drawLine(xCenter, yCenter, xMinute, yMinute);
//Draw hour hand
//由于时针有时在某两个数字之间,所以定义坐标时有些不同
int hLength=(int)(clockRadius*0.5);
int xHour=(int)(xCenter + hLength*Math.sin((hour%12 + minute/60.0)*(Math.PI*2/12)));
int yHour=(int)(yCenter - hLength*Math.cos((hour%12 + minute/60.0)*(Math.PI*2/12)));
g.setColor(Color.black);
g.drawLine(xCenter, yCenter, xHour, yHour);
}
public void setCurrentTime(){
//Construct a calendar for the current date and time
Calendar calendar=new GregorianCalendar();
//Set current hour,minute and second
this.hour=calendar.get(Calendar.HOUR_OF_DAY);
this.minute=calendar.get(Calendar.MINUTE);
this.second=calendar.get(Calendar.SECOND);
}
}