javafx 动态时钟

javafx 动态时钟,指针可旋转

成果展示

在这里插入图片描述

功能介绍

  1. 时钟显示
  2. 电子时间
  3. 校准当前时间
  4. 手动调整时间
  5. 整点报时功能
  6. 时间调整记录

代码

主方法:

package mnsz;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class DisplayClock extends Application {
	public void start(Stage primaryStage) {
		ClockPane clock = new ClockPane();

		clock.btOK.setOnAction(e -> clock.adjustClock());
		clock.btCurrentTime.setOnAction(e -> clock.setCurrentTime());

		clock.run();

		BorderPane pane = new BorderPane();
		pane.setPadding(new Insets(0, 0, 20, 0));
		pane.setCenter(clock);
		pane.setBottom(clock.adjustBlank());

		Scene scene = new Scene(pane, clock.getW(), clock.getH() + 200);
		primaryStage.setTitle("模拟时钟");
		primaryStage.setScene(scene);
		primaryStage.show();
	}

	public static void main(String[] args) {
		Application.launch(args);
	}
}

时钟类:

package mnsz;

import java.io.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.util.Duration;

public class ClockPane extends Pane implements Runnable {
	private int hour;
	private int minute;
	private int second;
	private double w = 600, h = 600;

	//时钟的半径及中心点的x、y坐标
	double clockRadius = Math.min(w, h) * 0.8 * 0.5;
	double centerX = w / 2;
	double centerY = h / 2;
	
	//修改时间及校准时间的面板
	Text tHour = new Text("调整时针(00~23)");
	Text tMinute = new Text("调整分针(00~59)");
	Text tSecond = new Text("调整秒针(00~59)");
	TextField tfHour = new TextField("12");
	TextField tfMinute = new TextField("59");
	TextField tfSecond = new TextField("55");
	Button btOK = new Button("设为以上时间");
	Button btCurrentTime = new Button("校准当前时间");

	//整点报时音乐
	String music1 = "file:///D:/Program%20Files/mnsz_music/mnsz_music.mp3";
	Media media1 = new Media(music1);
	MediaPlayer mp1 = new MediaPlayer(media1);

	//半点报时音乐
	String music2 = "file:///D:/Program%20Files/mnsz_music/mnsz_music.mp3";
	Media media2 = new Media(music2);
	MediaPlayer mp2 = new MediaPlayer(media2);
	
	//无参构造方法
	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;
	}

	public int getMinute() {
		return minute;
	}

	public void setMinute(int minute) {
		this.minute = minute;
	}

	public int getSecond() {
		return second;
	}

	public void setSecond(int seconds) {
		this.second = seconds;
	}

	public double getW() {
		return w;
	}

	public void setW(double w) {
		this.w = w;
	}

	public double getH() {
		return h;
	}

	public void setH(double h) {
		this.h = h;
	}
	
	//设置为系统时间方法
	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();
	}
	
	//将时间转换为字符
	public String timeToString() {
		StringBuilder sb = new StringBuilder();
		sb.append(hour < 10 ? "0" : "");
		sb.append(hour).append(":");
		sb.append(minute < 10 ? "0" : "");
		sb.append(minute).append(":");
		sb.append(second < 10 ? "0" : "");
		sb.append(second);
		return sb.toString();
	}

	//打印时钟
	public void paintClock() {
		calculateClock();
		getChildren().clear();

		//时钟圆
		Circle circle = new Circle(centerX, centerY, clockRadius);
		circle.setFill(Color.WHITE);
		circle.setStroke(Color.BLACK);

		//时针
		double sLength = clockRadius * 0.8;
		double secondX = centerX + sLength * Math.sin(second * (2 * Math.PI / 60));
		double secondY = centerY - sLength * Math.cos(second * (2 * Math.PI / 60));
		Line sLine = new Line(centerX, centerY, secondX, secondY);
		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);
		mLine.setStrokeWidth(2);

		//秒针
		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.0) * (2 * Math.PI / 12));
		Line hLine = new Line(centerX, centerY, hourX, hourY);
		hLine.setStroke(Color.GREEN);
		hLine.setStrokeWidth(4);

		//时钟中心点
		Circle circleCenter = new Circle(centerX, centerY, 5);
		
		//数字时钟
		Label l = new Label(timeToString());
		l.setLayoutX(273);
		l.setLayoutY(20);
		getChildren().addAll(circle, sLine, mLine, hLine, circleCenter,l);

		//1~12数字以及12个大刻度
		Text[] t = new Text[12];
		for (int i = 1; i <= 12; i++) {
			Circle circle12 = new Circle(centerX + Math.sin(i * Math.PI / 6) * (clockRadius),
					centerY - Math.cos(i * Math.PI / 6) * (clockRadius), 3);
			t[i - 1] = new Text(centerX - 4 + Math.sin(i * Math.PI / 6) * (clockRadius * 0.9),
					centerY + 5 - Math.cos(i * Math.PI / 6) * (clockRadius * 0.9), String.valueOf(i));
			getChildren().addAll(t[i - 1], circle12);
		}

		//每一分钟的小刻度
		for (int i = 1; i <= 60; i++) {
			Circle circle60 = new Circle(centerX + Math.sin(i * Math.PI / 30) * (clockRadius),
					centerY - Math.cos(i * Math.PI / 30) * (clockRadius), 2);
			getChildren().add(circle60);
		}
	}
	
	//修改时间的面板
	public VBox adjustBlank() {
		GridPane pane = new GridPane();
		pane.setAlignment(Pos.CENTER);
		pane.setHgap(5.5);
		pane.setVgap(5.5);

		VBox vBox = new VBox(5.5);
		vBox.setAlignment(Pos.CENTER);

		tfHour.setMaxWidth(50);
		tfMinute.setMaxWidth(50);
		tfSecond.setMaxWidth(50);
		btOK.setMaxWidth(150);
		btCurrentTime.setMaxWidth(150);

		pane.add(tHour, 0, 0);
		pane.add(tfHour, 1, 0);
		pane.add(tMinute, 0, 1);
		pane.add(tfMinute, 1, 1);
		pane.add(tSecond, 0, 2);
		pane.add(tfSecond, 1, 2);
		pane.add(btOK, 1, 3);
		vBox.getChildren().addAll(pane, btOK, btCurrentTime);
		return vBox;
	}

	//调整时间
	public void adjustClock() {
		if (Integer.parseInt(tfHour.getText()) >= 0 && Integer.parseInt(tfHour.getText()) < 24
				&& Integer.parseInt(tfMinute.getText()) >= 0 && Integer.parseInt(tfMinute.getText()) < 60
				&& Integer.parseInt(tfSecond.getText()) >= 0 && Integer.parseInt(tfSecond.getText()) < 60) {
			hour = Integer.parseInt(tfHour.getText());
			minute = Integer.parseInt(tfMinute.getText());
			second = Integer.parseInt(tfSecond.getText());
			writeFile();//将时间写入文件
			paintClock();
		}
	}

	//修改的时间写入文件
	public void writeFile() {
		File file = new File("clock.txt");
		try {
			if (!file.exists())
				file.createNewFile();
			InputStreamReader isr = new InputStreamReader(System.in);
			BufferedReader br = new BufferedReader(isr);
			FileWriter fos = new FileWriter(file, true);
			BufferedWriter bw = new BufferedWriter(fos);
			bw.write(timeToString() + "\r\n");
			br.close();
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//计算时间
	public void calculateClock() {
		if (second == 60) {
			second = 0;
			minute++;
		}
		if (minute == 60) {
			minute = 0;
			hour++;
		}
		if (hour == 24) {
			hour = 0;
		}
	}

	@Override
	public void run() {
		EventHandler<ActionEvent> eventHandler = e -> {
			setSecond(getSecond() + 1);
			paintClock();
			addVoice(getMinute(), getSecond(), mp1, mp2);
		};
		Timeline animation = new Timeline(new KeyFrame(Duration.millis(1000), eventHandler));
		animation.setCycleCount(Timeline.INDEFINITE);
		animation.play();
	}

	//整点半点播放音乐
	public void addVoice(int minute, int second, MediaPlayer mp1, MediaPlayer mp2) {
		if (minute == 0 && second == 0) {
			mp1.play();
			return;
		}
		if (minute == 0 && second == 15) {
			mp1.stop();
			return;
		}
		if (minute == 30 && second == 0) {
			mp2.play();
			return;
		}
		if (minute == 30 && second == 15) {
			mp2.stop();
			return;
		}
	}
}

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值