欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaFX实现简易时钟效果

程序员文章站 2022-03-10 14:24:56
本文实例为大家分享了javafx实现简易时钟效果的具体代码,供大家参考,具体内容如下首先要在面板中显示一个时钟,我们可以设计一个clockpane类来显示一个时钟。最终效果:若要绘制一个时钟,需要绘制...

本文实例为大家分享了javafx实现简易时钟效果的具体代码,供大家参考,具体内容如下

首先要在面板中显示一个时钟,我们可以设计一个clockpane类来显示一个时钟。

最终效果:

JavaFX实现简易时钟效果

若要绘制一个时钟,需要绘制一个圆并为秒钟、分钟和小时绘制三个指针。为了画一个指针,需要确定一条直线的两端:一端是时钟的*,位于(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())
  );
 }
}

程序简单解读:①在时间线动画的每个关键帧中,这个处理器每秒被调用一次。所以动画中的时间每秒被更新一次。②最后两个监听器是用来修改时钟的面板的大小的,将这个监听器和窗体的宽度和高度属性进行注册,从而在场景的宽度和高度改变的情况下可以重新设置面板大小。代码保证了时钟面板的大小和场景大小是同步的。

最后运行就能达到上面图所示的效果了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关标签: JavaFX 时钟