黑马程序员:论java挂钟的正确编写姿势

来源:互联网 发布:淘宝首页装修图片 编辑:程序博客网 时间:2024/04/27 13:37

android培训、java培训、期待与您交流!

编码思路:

1 因为是时钟,所以每一秒都是不同的。而这一秒和下一秒,就是两个不同的静态图像而已。所以应该用线程,然后每一秒检测一下当前时间,根据当前时间再绘制一幅图,调用repaint方法显示。


2 如何根据时间来绘制各个指针的长短?

   所谓的时针分针秒针,都是线而已。所以只要确定他们的起点和终点。其中起点毫无疑问是挂钟的中心点,也就是整个Panel的中点。而其终点则是根据时间来变化的。

   对于秒针来说,每一次移动都是1°。因为整个圆是360°,要60秒运行完,所以1秒要移动6°,然后转化为弧度制,即可得到第1秒秒针的终点坐标了。

  所以

   //秒针        int secondX=point.x+(int)(1*Math.sin(second*2*Math.PI/60.0));        int secondY=point.y-(int)(1*Math.cos(second*2*Math.PI/60.0));

   这样就可以获得第1秒时,秒针终点的位置。所以要获得每一秒秒针的位置,只需要用将上面的 1换成秒数就可以了

  分钟同理。

  牵扯到时针,处理方式就复杂了。因为时针的取值只有12个数字,分针和秒针都有60个数字。如果一之前的方式处理时针,效果就是时针到点的一瞬间转动了30°,为了解决该问题,在计算式加入了分钟值。用分钟值/60+小时数来确定其弧度。

//时针int hourX=point.x+(int)(hourHand*Math.sin(minu/60.0+hour)*Math.PI/6.0);int hourY=point.y-(int)(hourHand*Math.cos(minu/60.0+hour)*Math.PI/6.0);


3绘制表盘刻度

  一个圆是360°,12个小时就是12个主刻度,然后2个相邻刻度之间是5刻度。一共是12*6=60个刻度,每一个刻度之间相差6°(此结论似曾相识)。

 所以刻度的起点和终点坐标为:

int x2=point.x+(int)(radi*Math.sin(i*2*Math.PI/60.0));int y2=point.y-(int)(radi*Math.cos(i*2*Math.PI/60.0));

int x1=point.x+(int)((secondHand+1)*Math.sin(i*2*Math.PI/60.0));int y1=point.y-(int)((secondHand+1)*Math.cos(i*2*Math.PI/60.0));

或者

int x1=point.x+(int)((secondHand+10)*Math.sin(i*2*Math.PI/60.0));int y1=point.y-(int)((secondHand+10)*Math.cos(i*2*Math.PI/60.0));

之所以起点有差别,是因为主刻度是要突出一些。


然后编写代码

package new_clock;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Graphics;import java.awt.Point;import java.text.DateFormat;import java.util.Calendar;import java.util.Date;import javax.swing.JLabel;import javax.swing.JPanel;public class Clock extends JPanel implements Runnable{private JLabel jl;private DateFormat df;public Clock(){jl=new JLabel();jl.setHorizontalAlignment(JLabel.CENTER);this.setLayout(new BorderLayout());this.add(jl,BorderLayout.SOUTH);df=DateFormat.getDateInstance();//获取日期jl.setText(df.format(new Date()));new Thread(this).start();}@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}repaint();}}@Overrideprotected void paintComponent(Graphics g) {// TODO Auto-generated method stubsuper.paintComponent(g);this.drawClock(this,g);}private void drawClock(Clock clock, Graphics g) {Calendar cal=Calendar.getInstance();//获得时间信息int hour=cal.get(Calendar.HOUR);int minu=cal.get(Calendar.MINUTE);int second=cal.get(Calendar.SECOND);//获取表盘半径int width=clock.getWidth();int height=clock.getHeight();int len=width>height?height:width;int dia=(int) (len*0.8);int radi=dia/2;//获取各个指针的长度int secondHand=(int) (radi*0.8);int minuHand=(int) (secondHand*0.8);int hourHand=(int) (minuHand*0.8);//确定指针的一端Point point=new Point(width/2,height/2);//确定指针的另一端//秒针int secondX=point.x+(int)(secondHand*Math.sin(second*2*Math.PI/60.0));int secondY=point.y-(int)(secondHand*Math.cos(second*2*Math.PI/60.0));//分针int minuX=point.x+(int)(minuHand*Math.sin(minu*2*Math.PI/60.0));int minuY=point.y-(int)(minuHand*Math.cos(minu*2*Math.PI/60.0));//时针int hourX=point.x+(int)(hourHand*Math.sin(minu/60.0+hour)*Math.PI/6.0);int hourY=point.y-(int)(hourHand*Math.cos(minu/60.0+hour)*Math.PI/6.0);//绘制表盘刻度Graphics g2d=(Graphics)g;g.drawOval(point.x-radi, point.y-radi, dia, dia);//绘制刻度for(int i=0;i<60;i++){int x2=point.x+(int)(radi*Math.sin(i*2*Math.PI/60.0));int y2=point.y-(int)(radi*Math.cos(i*2*Math.PI/60.0));if(i%5==0){int x1=point.x+(int)((secondHand+1)*Math.sin(i*2*Math.PI/60.0));int y1=point.y-(int)((secondHand+1)*Math.cos(i*2*Math.PI/60.0));g2d.drawLine(x1, y1, x2, y2);int temp=i/5;if(temp==0){temp=12;}g2d.drawString(String.valueOf(temp), x2, y2);}else{int x1=point.x+(int)((secondHand+10)*Math.sin(i*2*Math.PI/60.0));int y1=point.y-(int)((secondHand+10)*Math.cos(i*2*Math.PI/60.0));g2d.drawLine(x1, y1, x2, y2);}}//绘制时针、分针、秒针g2d.setColor(Color.BLACK);//绘制时针g2d.drawLine(point.x, point.y, secondX, secondY);//绘制时针g2d.drawLine(point.x, point.y, minuX,minuY);//绘制时针g2d.drawLine(point.x, point.y, hourX, hourY);}}

然后编写测试类:

package new_clock;import javax.swing.JFrame;public class Demo {public static void main(String[] args) {JFrame jf=new JFrame("挂钟");jf.add(new Clock());jf.setVisible(true);jf.setSize(300,300);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}

运行结果:




0 0
原创粉丝点击