javaFX编写精美动态时钟 14.27(编写一个详细的时钟)修改14.12节的ClockPane类
先看效果图:
上代码
绘制时钟面板类NewClockPane
package com.example.w9;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 NewClockPane extends Pane { private int hour; private int minute; private int second; private Line[] linesList = new Line[60]; private Text[] textsList = new Text[12]; public NewClockPane(){ setCurrentTime(); } public NewClockPane(int hour, int minute, int second){ this.hour = hour; this.minute = minute; this.second = second; } 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 second) { this.second = second; } 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(); } private void paintClock(){ double clockRadius = Math.min(getWidth(), getHeight()) * 0.8 * 0.5; double centerX = getWidth() / 2; //继承父类Pane的方法, 保证时钟居中 double centerY = getHeight() / 2; Circle circle = new Circle(centerX, centerY, clockRadius); circle.setFill(Color.rgb(240,247,201)); circle.setStroke(Color.rgb(254,16,94)); circle.setStrokeWidth(5); for (int i = 0; i < this.linesList.length; i++){ if (i == 0){// double angle = Math.PI / 2 - i * Math.PI / 30; Line line = new Line( centerX + 0.85 * clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - 0.85 * clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30), centerX + clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30)); line.setStroke(Color.rgb(254,16,94)); this.linesList[i] = line; int num = i / 5; Text text = new Text(centerX +0.8 * clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - 0.8 * clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30), 12 +""); this.textsList[num] = text; } if (i % 5 == 0 && i != 0){// double angle = Math.PI / 2 - i * Math.PI / 30; Line line = new Line( centerX + 0.85 * clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - 0.85 * clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30), centerX + clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30)); line.setStroke(Color.rgb(254,16,94)); this.linesList[i] = line; int num = i / 5; Text text = new Text(centerX +0.8 * clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - 0.8 * clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30), num+""); this.textsList[num] = text; } else {// Double angle = Math.PI / 2 - i * Math.PI / 30; Line line = new Line( centerX + 0.9 * clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - 0.9 * clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30), centerX + clockRadius * Math.cos(Math.PI / 2 - i * Math.PI / 30), centerY - clockRadius * Math.sin(Math.PI / 2 - i * Math.PI / 30)); line.setStroke(Color.rgb(254,16,94)); this.linesList[i] = line; } } double sLength = clockRadius * 0.8; double secondX = centerX + sLength * Math.sin(this.second * (2 * Math.PI / 60)); double secondY= centerY - sLength * Math.cos(this.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(this.minute * (2 * Math.PI / 60)); double minuteY = centerY - mLength * Math.cos(this.minute * (2 * Math.PI / 60)); Line mLine = new Line(centerX, centerY, minuteX, minuteY); mLine.setStrokeWidth(3); mLine.setStroke(Color.BLUE); double hLength = clockRadius * 0.5; double hourX = centerX + hLength * Math.sin((this.hour % 12 + this.minute / 60.0) * (2 * Math.PI / 12)); double hourY = centerY - hLength * Math.cos((this.hour % 12 + this.minute / 60.0) * (2 * Math.PI / 12)); Line hLine = new Line(centerX, centerY, hourX, hourY); hLine.setStrokeWidth(5); hLine.setStroke(Color.GREEN); getChildren().clear(); getChildren().add(circle); getChildren().add(sLine); getChildren().add(mLine); getChildren().add(hLine); for (int i = 0; i < this.linesList.length; i++){ if (i % 5 ==0){ getChildren().add(this.linesList[i]); getChildren().add(this.textsList[i / 5]); } else { getChildren().add(this.linesList[i]); } } } @Override public void setWidth(double width){ super.setWidth(width); paintClock(); } @Override protected void setHeight(double height) { super.setHeight(height); paintClock(); }}
时钟上的刻度坐标和数字坐标计算原理:
显示类DisplayClock
package com.example.w9;import javafx.animation.KeyFrame;import javafx.animation.Timeline;import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.Label;import javafx.scene.layout.BorderPane;import javafx.scene.text.Font;import javafx.stage.Stage;import javafx.util.Duration;public class DisplayClock extends Application { public static void main(String[] args) {launch();} @Override public void start(Stage primaryStage){ NewClockPane newClockPane = new NewClockPane(); BorderPane borderPane = new BorderPane(); EventHandler<ActionEvent> eventHandler = event -> { newClockPane.setCurrentTime(); String timeString = newClockPane.getHour() + " : " + newClockPane.getMinute() + " : " + newClockPane.getSecond(); Label timeLabel = new Label(timeString); timeLabel.setFont(new Font("黑体", 16)); borderPane.setCenter(newClockPane); borderPane.setBottom(timeLabel); BorderPane.setAlignment(timeLabel, Pos.TOP_CENTER); }; Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1000), eventHandler)); //永久动画 timeline.setCycleCount(Timeline.INDEFINITE); timeline.play(); Scene scene = new Scene(borderPane, 600, 600); primaryStage.setTitle("MyClock"); primaryStage.setScene(scene); primaryStage.show(); }}