analog_clock/AnalogClockDrawing/src/analogclock/AnalogClockDrawing.java @ e0735667
| 9f8dc300 | TAKAHASHI, Toru | /*
|
||
* Copyright © 2014 TAKAHASHI,Toru
|
||||
*/
|
||||
package analogclock;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import java.util.stream.IntStream;
|
||||
import javafx.animation.Animation;
|
||||
| 88e074e8 | TAKAHASHI, Toru | import javafx.animation.Interpolator;
|
||
import javafx.animation.RotateTransition;
|
||||
| 9f8dc300 | TAKAHASHI, Toru | import javafx.application.Application;
|
||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
| 88e074e8 | TAKAHASHI, Toru | import javafx.scene.layout.Pane;
|
||
import javafx.scene.layout.StackPane;
|
||||
| 9f8dc300 | TAKAHASHI, Toru | import javafx.scene.paint.Color;
|
||
import javafx.scene.paint.CycleMethod;
|
||||
import javafx.scene.paint.RadialGradient;
|
||||
import javafx.scene.paint.Stop;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.scene.shape.Line;
|
||||
import javafx.scene.shape.LineTo;
|
||||
import javafx.scene.shape.MoveTo;
|
||||
import javafx.scene.shape.Path;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
/**
|
||||
* アナログ時計(長針、短針、秒針)を表示するプログラム。
|
||||
*
|
||||
* @author TAKAHASHI,Toru
|
||||
*/
|
||||
public class AnalogClockDrawing extends Application {
|
||||
| 4838a05f | TAKAHASHI, Toru | private static final double UNIT_SIZE = 100d;
|
||
| 9f8dc300 | TAKAHASHI, Toru | |||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
| 88e074e8 | TAKAHASHI, Toru | StackPane root = new StackPane();
|
||
Node clockDial = createClockDial();
|
||||
Node hourHand = createHourHand();
|
||||
Node minuteHand = createMinuteHand();
|
||||
Node secondHand = createSecondHand();
|
||||
Node centerPoint = createCenter();
|
||||
| 9f8dc300 | TAKAHASHI, Toru | root.getChildren().addAll(
|
||
| 88e074e8 | TAKAHASHI, Toru | clockDial, hourHand, minuteHand, secondHand, centerPoint
|
||
| 9f8dc300 | TAKAHASHI, Toru | );
|
||
LocalTime time = LocalTime.now();
|
||||
| 88e074e8 | TAKAHASHI, Toru | RotateTransition secondsTransition = createRotateTransition(Duration.seconds(60), secondHand, getSecondsAngle(time));
|
||
secondsTransition.play();
|
||||
RotateTransition minuteTransition = createRotateTransition(Duration.minutes(60), minuteHand, getMinuteAgnel(time));
|
||||
minuteTransition.play();
|
||||
RotateTransition hourTransition = createRotateTransition(Duration.hours(12), hourHand, getHourAngle(time));
|
||||
hourTransition.play();
|
||||
| 9f8dc300 | TAKAHASHI, Toru | |||
| 88e074e8 | TAKAHASHI, Toru | Scene scene = new Scene(root);
|
||
primaryStage.setTitle("Clock");
|
||||
| 9f8dc300 | TAKAHASHI, Toru | primaryStage.setScene(scene);
|
||
primaryStage.show();
|
||||
}
|
||||
| 88e074e8 | TAKAHASHI, Toru | RotateTransition createRotateTransition(Duration duration, Node node, int startAngle) {
|
||
RotateTransition rt = new RotateTransition(duration, node);
|
||||
rt.setFromAngle(startAngle);
|
||||
rt.setByAngle(360);
|
||||
rt.setCycleCount(Animation.INDEFINITE);
|
||||
rt.setInterpolator(Interpolator.LINEAR);
|
||||
return rt;
|
||||
}
|
||||
Node createClockDial() {
|
||||
Pane pane = new Pane();
|
||||
pane.getChildren().addAll(createCircle(), createTickMarks());
|
||||
return pane;
|
||||
| 9f8dc300 | TAKAHASHI, Toru | }
|
||
// 時計の文字盤(背景)を作成する
|
||||
| 88e074e8 | TAKAHASHI, Toru | Node createCircle() {
|
||
| 9f8dc300 | TAKAHASHI, Toru | RadialGradient gradient = new RadialGradient(
|
||
0, 0, 0.5, 0.5, 0.5, true, CycleMethod.NO_CYCLE,
|
||||
new Stop(0.8, Color.WHITE), new Stop(0.9, Color.BLACK), new Stop(0.95, Color.WHITE), new Stop(1.0, Color.BLACK)
|
||||
);
|
||||
Circle circle = new Circle(UNIT_SIZE, UNIT_SIZE, UNIT_SIZE, gradient);
|
||||
return circle;
|
||||
}
|
||||
// 時計の文字盤(分刻み)を作成する
|
||||
Node createTickMarks() {
|
||||
Group tickMarkGroup = new Group();
|
||||
List<Node> tickMarks = IntStream.range(0, 60)
|
||||
.mapToObj(this::createTickMark)
|
||||
.collect(toList());
|
||||
tickMarkGroup.getChildren().addAll(tickMarks);
|
||||
return tickMarkGroup;
|
||||
}
|
||||
// 時計の文字盤の分刻みの1つを作成する
|
||||
Node createTickMark(int n) {
|
||||
Line line;
|
||||
if (n % 5 == 0) {
|
||||
line = new Line(UNIT_SIZE, UNIT_SIZE * 0.12, UNIT_SIZE, UNIT_SIZE * 0.2);
|
||||
} else {
|
||||
line = new Line(UNIT_SIZE, UNIT_SIZE * 0.15, UNIT_SIZE, UNIT_SIZE * 0.16);
|
||||
}
|
||||
line.getTransforms().add(new Rotate(360 / 60 * n, UNIT_SIZE, UNIT_SIZE));
|
||||
line.setStrokeWidth(2);
|
||||
return line;
|
||||
}
|
||||
// 時計の中心点を作成する
|
||||
Node createCenter() {
|
||||
return new Circle(UNIT_SIZE, UNIT_SIZE, UNIT_SIZE * 0.05, Color.BLACK);
|
||||
}
|
||||
// 時計の短針を作成する
|
||||
Node createHourHand() {
|
||||
| 88e074e8 | TAKAHASHI, Toru | Pane pane = new Pane();
|
||
pane.setPrefSize(UNIT_SIZE * 2, UNIT_SIZE * 2);
|
||||
| 4838a05f | TAKAHASHI, Toru | Node hourHand = createHourOrMinuteHand(UNIT_SIZE * 0.4, Color.BLACK);
|
||
| 88e074e8 | TAKAHASHI, Toru | pane.getChildren().add(hourHand);
|
||
return pane;
|
||||
| 9f8dc300 | TAKAHASHI, Toru | }
|
||
// 時計の長針を作成する
|
||||
Node createMinuteHand() {
|
||||
| 88e074e8 | TAKAHASHI, Toru | Pane pane = new Pane();
|
||
pane.setPrefSize(UNIT_SIZE * 2, UNIT_SIZE * 2);
|
||||
| 4838a05f | TAKAHASHI, Toru | Node minuteHand = createHourOrMinuteHand(UNIT_SIZE * 0.2, Color.BLACK);
|
||
| 88e074e8 | TAKAHASHI, Toru | pane.getChildren().add(minuteHand);
|
||
return pane;
|
||||
| 9f8dc300 | TAKAHASHI, Toru | }
|
||
// 時計の秒針を作成する
|
||||
| 88e074e8 | TAKAHASHI, Toru | Node createSecondHand() {
|
||
Pane pane = new Pane();
|
||||
pane.setPrefSize(UNIT_SIZE * 2, UNIT_SIZE * 2);
|
||||
| 9f8dc300 | TAKAHASHI, Toru | Line line = new Line(UNIT_SIZE, UNIT_SIZE * 1.1, UNIT_SIZE, UNIT_SIZE * 0.2);
|
||
| 88e074e8 | TAKAHASHI, Toru | pane.getChildren().add(line);
|
||
return pane;
|
||||
| 9f8dc300 | TAKAHASHI, Toru | }
|
||
// 時計の針を作成する
|
||||
| 4838a05f | TAKAHASHI, Toru | Node createHourOrMinuteHand(double stretchRelativeToRim, Color color) {
|
||
| 9f8dc300 | TAKAHASHI, Toru | Path path = new Path(
|
||
new MoveTo(UNIT_SIZE, UNIT_SIZE),
|
||||
new LineTo(UNIT_SIZE * 0.9, UNIT_SIZE * 0.9),
|
||||
new LineTo(UNIT_SIZE, stretchRelativeToRim),
|
||||
new LineTo(UNIT_SIZE * 1.1, UNIT_SIZE * 0.9),
|
||||
new LineTo(UNIT_SIZE, UNIT_SIZE)
|
||||
);
|
||||
path.setFill(color);
|
||||
path.setStroke(Color.TRANSPARENT);
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
private int getSecondsAngle(LocalTime time) {
|
||||
return time.getSecond() * 360 / 60;
|
||||
}
|
||||
private int getMinuteAgnel(LocalTime time) {
|
||||
| 6b81b8b1 | TAKAHASHI, Toru | return (int) ((time.getMinute() + time.getSecond() / 60d) * 360 / 60);
|
||
| 9f8dc300 | TAKAHASHI, Toru | }
|
||
private int getHourAngle(LocalTime time) {
|
||||
| 6b81b8b1 | TAKAHASHI, Toru | return (int) ((time.getHour() % 12 + time.getMinute() / 60d + time.getSecond() / 3600d) * 360 / 12);
|
||
| 9f8dc300 | TAKAHASHI, Toru | }
|
||
}
|