1+ package ch_15 ;
2+ 3+ import javafx .animation .PathTransition ;
4+ import javafx .application .Application ;
5+ import javafx .scene .Scene ;
6+ import javafx .scene .layout .Pane ;
7+ import javafx .scene .paint .Color ;
8+ import javafx .scene .shape .Arc ;
9+ import javafx .scene .shape .Circle ;
10+ import javafx .scene .shape .Line ;
11+ import javafx .stage .Stage ;
12+ import javafx .util .Duration ;
13+ 14+ /**
15+ * **15.31 (Geometry: pendulum) Write a program that animates a pendulum swinging,
16+ * as shown in Figure 15.35. Press the UP arrow key to faster the speed and the
17+ * DOWN key to slower it. Press the S key to stop animation and the R key to
18+ * resume it.
19+ */
20+ public class Exercise15_31 extends Application {
21+ private final double sceneWidth = 400 ;
22+ 23+ private final double sceneHeight = 400 ;
24+ 25+ @ Override
26+ public void start (Stage primaryStage ) throws Exception {
27+ PendulumPane pendulumPane = new PendulumPane (sceneWidth , sceneHeight );
28+ Scene scene = new Scene (pendulumPane , sceneWidth , sceneHeight );
29+ primaryStage .setTitle (getClass ().getName ());
30+ primaryStage .setScene (scene );
31+ primaryStage .show ();
32+ 33+ pendulumPane .play ();
34+ 35+ scene .setOnKeyPressed (e -> {
36+ switch (e .getCode ()) {
37+ case UP :
38+ pendulumPane .faster ();
39+ break ;
40+ case DOWN :
41+ pendulumPane .slower ();
42+ break ;
43+ }
44+ });
45+ }
46+ }
47+ 48+ class PendulumPane extends Pane {
49+ PathTransition animationPath ;
50+ Circle referenceCircleTop ;
51+ Circle referenceCircleBottom ;
52+ Line shaft ;
53+ Arc pendulumSwingArc ;
54+ 55+ PendulumPane (double width , double height ) {
56+ setPrefWidth (width );
57+ setPrefHeight (height );
58+ pendulumSwingArc = new Arc (width / 2 ,
59+ height * 0.8 ,
60+ width * 0.15 ,
61+ width * 0.15 ,
62+ 180 ,
63+ 180 );
64+ pendulumSwingArc .setFill (Color .TRANSPARENT );
65+ pendulumSwingArc .setStroke (Color .BLACK );
66+ 67+ referenceCircleBottom = new Circle (pendulumSwingArc .getCenterX () - pendulumSwingArc .getRadiusX (),
68+ pendulumSwingArc .getCenterY (),
69+ 10 );
70+ referenceCircleTop = new Circle (pendulumSwingArc .getCenterX (),
71+ pendulumSwingArc .getCenterY () - height / 2 ,
72+ referenceCircleBottom .getRadius () / 2 );
73+ pendulumSwingArc = new Arc (referenceCircleTop .getCenterX (),
74+ referenceCircleTop .getCenterY (),
75+ width / 2 ,
76+ height / 2 ,
77+ 240 ,
78+ 60 );
79+ shaft = new Line (
80+ referenceCircleTop .getCenterX (), referenceCircleTop .getCenterY (),
81+ referenceCircleBottom .getCenterX (), referenceCircleBottom .getCenterY ());
82+ 83+ shaft .endXProperty ().bind (referenceCircleBottom .translateXProperty ().add (referenceCircleBottom .getCenterX ()));
84+ shaft .endYProperty ().bind (referenceCircleBottom .translateYProperty ().add (referenceCircleBottom .getCenterY ()));
85+ animationPath = new PathTransition ();
86+ animationPath .setDuration (Duration .millis (4000 ));
87+ animationPath .setPath (pendulumSwingArc );
88+ animationPath .setNode (referenceCircleBottom );
89+ animationPath .setOrientation (PathTransition .OrientationType .NONE );
90+ animationPath .setCycleCount (PathTransition .INDEFINITE );
91+ animationPath .setAutoReverse (true );
92+ 93+ getChildren ().addAll (referenceCircleBottom , referenceCircleTop , shaft );
94+ 95+ }
96+ 97+ public void play () {
98+ animationPath .play ();
99+ }
100+ 101+ 102+ public void faster () {
103+ animationPath .rateProperty ().set (animationPath .getRate () + 1 );
104+ }
105+ 106+ public void slower () {
107+ animationPath .rateProperty ().set (animationPath .getRate () - 1 );
108+ }
109+ }
0 commit comments