官术网_书友最值得收藏!

Clock demo

Let's apply some of the stuff we learned in this Chapter to the Clock demo we started in the previous chapter.

The digital clock is not as fun as an analog one, so let's add hands to it.

We need three hands—hours, minutes, and seconds. We'll use a simple line for the seconds hand and slightly more complex path shapes for the hour and minute ones. For example, here is the path for the minute hand:

Path minuteHand = new Path(
new MoveTo(0, 0),
new LineTo(15, -5),
new LineTo(100,0),
new LineTo(15,5),
new ClosePath());
minuteHand.setFill(Color.DARKGRAY);

This code gives us not the prettiest but a conveniently simple hand. We'll work on making it nicer in following chapters:

To show time, the hand has to rotate. We'll use the Rotate transformation. We need to rotate the hand around the leftmost point, not the center, so we set the pivot point to zero coordinates:

Rotate rotateMinutesHand = new Rotate();
rotateMinutesHand.setPivotX(0);
rotateMinutesHand.setPivotY(0);
minuteHand.getTransforms().add(rotateMinutesHand);

Now, we can control the time set by modifying the angle for this Rotate transformation.

Also, our hand is inside our layout manager, which tries to center it around Path central point as well. But, we want to have a center in the local coordinates (0,0). To achieve that, we will translate our hand left by half of its actual size:

minuteHand.setTranslateX( minuteHand.getBoundsInLocal().getWidth()/2 );

For a better understanding, take a look at the ScenicView screenshot for this code—the dashed box is layoutBounds and the colored rectangle is boundsInParent, which changes after every rotation:

Here is the full code:

public class ClockTwo extends Application {
private final Text txtTime = new Text();

private Rotate rotateSecondHand = new Rotate(0,0,0);
private Rotate rotateMinuteHand = new Rotate(0,0,0);
private Rotate rotateHourHand = new Rotate(0,0,0);

private Thread timer = new Thread(() -> {
SimpleDateFormat dt = new SimpleDateFormat("hh:mm:ss");
Date now = new Date();
String time = dt.format(now);

Platform.runLater(()-> {
// updating live UI object requires JavaFX App Thread
rotateSecondHand.setAngle(now.getSeconds() * 6 - 90);
rotateMinuteHand.setAngle(now.getMinutes()* 6 - 90);
rotateHourHand.setAngle(now.getHours()* 30 - 90);
txtTime.setText(time);
});
try {
// running "long" operation not on UI thread
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
});

@Override
public void start(Stage stage) {
// create minutes hand
Path minuteHand = new Path(
new MoveTo(0, 0),
new LineTo(15, -5),
new LineTo(100,0),
new LineTo(15,5),
new ClosePath());
minuteHand.setFill(Color.DARKGRAY);
minuteHand.getTransforms().add(rotateMinuteHand);
minuteHand.setTranslateX(minuteHand.getBoundsInLocal().getWidth()/2);

// create second hand
Line secondHand = new Line(0,0, 90, 0);
secondHand.getTransforms().add(rotateSecondHand);
secondHand.setTranslateX(secondHand.getBoundsInLocal().getWidth()/2);

// create hour hand
Path hourHand = new Path(
new MoveTo(0, 0),
new LineTo(20, -8),
new LineTo(60,0),
new LineTo(20,8),
new ClosePath());
hourHand.setFill(Color.LIGHTGRAY);
hourHand.getTransforms().add(rotateHourHand);
hourHand.setTranslateX(hourHand.getBoundsInLocal().getWidth()/2);

BorderPane root = new BorderPane();
root.setCenter(new StackPane(minuteHand, hourHand, secondHand));
root.setBottom(txtTime);
BorderPane.setAlignment(txtTime, Pos.CENTER);

Scene scene = new Scene(root, 400, 350);
stage.initStyle(StageStyle.UTILITY);
stage.setScene(scene);
stage.setTitle("Clock, chapter 2");

timer.setDaemon(true);
timer.start();
stage.show();
System.out.println(minuteHand.getBoundsInLocal().getWidth());
}

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

The clock will appear as follows:

主站蜘蛛池模板: 鹿邑县| 伊吾县| 陆良县| 化德县| 馆陶县| 丰镇市| 车险| 大关县| 习水县| 田阳县| 锡林郭勒盟| 樟树市| 九龙县| 宕昌县| 安新县| 永康市| 灵宝市| 阜阳市| 武义县| 化州市| 历史| 清远市| 郯城县| 黄骅市| 大厂| 新邵县| 崇明县| 宜宾市| 千阳县| 临汾市| 安岳县| 中西区| 宿迁市| 上饶县| 长顺县| 峨眉山市| 房产| 玉田县| 吐鲁番市| 荔浦县| 黄陵县|