黑马程序员:论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
- 黑马程序员:论java挂钟的正确编写姿势
- 黑马程序员:论记事本的正确编写姿势
- 黑马程序员:论面向对象编程的正确姿势
- 黑马程序员:论多线程的正确使用姿势
- 黑马程序员:论反射的正确姿势以及应用范围
- 程序员的TokyoHot正确姿势
- 趣图丨程序员过万圣节的正确姿势
- 黑马程序员:论快速排序的实现姿势
- HDU 5047:JAVA输入输出的正确姿势
- Java getInstance() 单例的正确姿势
- java读取文件的正确姿势
- Java单例的正确使用姿势
- 【Java】jdk8 Optional 的正确姿势
- 使用 Java 8 Optional 的正确姿势
- 【Java】jdk8 Optional 的正确姿势
- 使用java 8 Optional 的正确姿势
- Java 同步锁的正确姿势
- Java 8 Optional的正确姿势
- java SE1.6中的Synchronized原理
- 深入理解ssh端口转发细节
- hdu5144 物理+三分
- Codeforces 495 A. Digital Counterr && Codeforces Round #282 (Div. 2)
- 【浅墨Unity3D Shader编程】之四 热带雨林篇: 剔除、深度测试、Alpha测试以及基本雾效合辑
- 黑马程序员:论java挂钟的正确编写姿势
- 详解Android动画之Tween Animation
- LeetCode OJ 之 Find Minimum in Rotated Sorted Array (查找旋转有序数组中的最小值)
- php cURL
- 常用到的Linux命令总结---不断更新
- Linux2.6下ESP包解析流程
- android自定义view显示歌词
- 【设计模式】对象创建—创建型模式(2)
- 变量的作用域