JavaFX实现简易时钟效果
本文实例为大家分享了javafx实现简易时钟效果的具体代码,供大家参考,具体内容如下
首先要在面板中显示一个时钟,我们可以设计一个clockpane类来显示一个时钟。
最终效果:
若要绘制一个时钟,需要绘制一个圆并为秒钟、分钟和小时绘制三个指针。为了画一个指针,需要确定一条直线的两端:一端是时钟的*,位于(centerx,centery);另外一端位于(endx,endy),由一下公式来确定:
endx=centerx+handlength×sin(θ)
endy=centery-handlength×cos(θ)
(其中θ是指针和竖直方向12点的夹角)
因为一分钟有60秒,所以第2个指针的角度是:second×(2π/60)
分钟的位置由分钟和秒钟来决定。包含秒数的确切分钟数是minu+second/60。例如,如时间是3分30秒,那么总的分钟数就是3.5。由于一小时有60分钟,因此分针的角度是: (minute+second/60)×(2π/12)
由于一个圆被分为12个小时,所以时针的角度是: (hour+minute/60+second/(60×60))×(2π/12)
为了简化计算,在计算分针和时针角度的时候,可以忽略秒针,因为它们数字太小,基本可以忽略。因此,秒针、分针以及时针的端点可以如下计算:
secondx = centerx + secondhandlength × sin(second × (2π/60))
secondy = centery - secondhandlength × cos(second × (2π/60))
minutex = centerx + minutehandlength × sin(minute × (2π/60))
minutey = centery - minutehandlength × cos(minute × (2π/60))
hourx = centerx + hourhandlength × sin((hour+minute/60) × (2π/12))
hourx = centerx + hourhandlength × sin((hour+minute/60) × (2π/12))
这样就得到了clockpane类的实现程序:
package com.company; import javafx.scene.layout.pane; import javafx.scene.paint.color; import javafx.scene.shape.circle; import javafx.scene.shape.line; import javafx.scene.text.text; import java.util.calendar; import java.util.gregoriancalendar; public class clockpane extends pane{ private int hour; private int minute; private int second; private double w=250,h=250; public clockpane() { setcurrenttime(); } public clockpane(int hour,int minute,int second) { this.hour=hour; this.minute=minute; this.second=second; paintclock(); } public int gethour() { return hour; } public void sethour(int hour) { this.hour=hour; paintclock(); } public int getminute() { return minute; } public void setminute(int minute) { this.minute=minute; paintclock(); } public int getsecond() { return second; } public void setsecond(int second) { this.second=second; paintclock(); } public double getw() { return w; } public void setw(double w) { this.w=w; paintclock(); } public double geth() { return h; } public void seth(double h) { this.h=h; paintclock(); } public void setcurrenttime() { calendar calendar=new gregoriancalendar(); this.hour=calendar.get(calendar.hour_of_day); this.minute=calendar.get(calendar.minute); this.second=calendar.get(calendar.second); paintclock(); } protected void paintclock() { double clockradius=math.min(w,h)*0.8*0.5; double centerx=w/2; double centery=h/2; circle circle=new circle(centerx,centery,clockradius); circle.setfill(color.white); circle.setstroke(color.black); text t1=new text(centerx-5,centery-clockradius+12,"12"); text t2=new text(centerx-clockradius+3,centery+5,"9"); text t3=new text(centerx+clockradius-10,centery+3,"3"); text t4=new text(centerx-3,centery+clockradius-3,"6"); double slength=clockradius*0.8; double scondx=centerx+slength*math.sin(second*(2*math.pi/60)); double scondy=centery-slength*math.cos(second*(2*math.pi/60)); line sline=new line(centerx,centery,scondx,scondy); sline.setstroke(color.red); double mlength=clockradius*0.65; double minutex=centerx+mlength*math.sin(minute*(2*math.pi/60)); double minutey=centery-mlength*math.cos(minute*(2*math.pi)/60); line mline=new line(centerx,centery,minutex,minutey); mline.setstroke(color.blue); double hlength=clockradius*0.5; double hourx=centerx+hlength*math.sin((hour%12+minute/60.0)*(2*math.pi/12)); double houry=centery-hlength*math.cos((hour%12+minute/60)*(2*math.pi/12)); line hline=new line(centerx,centery,hourx,houry); hline.setstroke(color.green); getchildren().clear(); getchildren().addall(circle,t1,t2,t3,t4,sline,mline,hline); } }
对程序的简要解读:①java api的gregoriancalendar类可以使用它的无参构造方法来商城一个具有当前时间的calendar实例。可以从一个calendar对象,通过调用它的get(calendar.hour)、get(calendar.minute)和get(calendar.second)方法来返回小时、分钟以及秒钟。②因为paintclock()方法在任何一个新的属性(hour、minute、second、w以及h)被设置的时候调用,所以之前的内容从面板中被清除。
然后就需要设计一个clockanimation类来显示时钟的动画
timeline类可以用于通过使用一个或者更多的keyframe(关键帧)来编写任意动画。
你可以用timeline来控制时钟的重绘,代码如下:
package com.company; import javafx.animation.timeline; import javafx.application.application; import javafx.geometry.pos; import javafx.scene.scene; import javafx.scene.layout.borderpane; import javafx.stage.stage; import javafx.util.duration; import javafx.event.actionevent; import javafx.event.eventhandler; import javafx.animation.keyframe; import javafx.scene.control.label; public class clockanimation extends application { @override public void start(stage primarystage) { clockpane clock=new clockpane(); borderpane borderpane=new borderpane(); eventhandler<actionevent> eventhandler=e -> { clock.setcurrenttime(); string timestring=clock.gethour()+":"+clock.getminute()+":"+clock.getsecond(); label lblcurrenttime=new label(timestring); borderpane.setcenter(clock); borderpane.setbottom(lblcurrenttime); borderpane.setalignment(lblcurrenttime, pos.top_center); }; timeline animation=new timeline(new keyframe(duration.millis(1000),eventhandler)); animation.setcyclecount(timeline.indefinite); animation.play(); scene scene=new scene(borderpane,250,250); primarystage.settitle("clockanimation"); primarystage.setscene(scene); primarystage.show(); borderpane.widthproperty().addlistener(ov -> clock.setw(borderpane.getwidth()) ); borderpane.heightproperty().addlistener(ov -> clock.seth(borderpane.getheight()) ); } }
程序简单解读:①在时间线动画的每个关键帧中,这个处理器每秒被调用一次。所以动画中的时间每秒被更新一次。②最后两个监听器是用来修改时钟的面板的大小的,将这个监听器和窗体的宽度和高度属性进行注册,从而在场景的宽度和高度改变的情况下可以重新设置面板大小。代码保证了时钟面板的大小和场景大小是同步的。
最后运行就能达到上面图所示的效果了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。