What do you know about the code changes that were just introduced into the codebase? When will you notice if something goes wrong?
This user guide provides a brief history of Java EE/Jakarta EE and a detailed overview of some of the specifications that will be updated in Jakarta EE 11.
Azul Platform Core is the #1 Oracle Java alternative, offering OpenJDK support for more versions (including Java 6 & 7) and more configurations for the greatest business value and lowest TCO.
Contact us to get your ad seen by thousands of users every day!
[email protected]"The only way to learn mathematics is to do mathematics." – Paul Halmos[1]
Welcome toCreating a JavaFX World Clock from Scratch Part 2!
This is the second installment of a series of blog entries on how I created a "sci-fi" looking world clock using JavaFX.
If you have not read Part 1[2] please see the introduction section of theCreating a JavaFX World Clock from Scratch (Part 1)[2].
In Part 2, I will show you how I animate the clock face's hands using basic trigonometry. If you want to skip the tutorial and go straight to the source code head over to GitHub WorldClock[4]
Creating a JavaFX World Clock from Scratch (Part 2)
First lets give a quick recap of Part 1. In the first part I discussed my design workflow, then later I mention tools such as a WYSIWYG graphical editor called Scene Builder[5]. Scene Builder is a tool to allows you to style shapes and to layout nodes onto the JavaFX scene graph.
I want to give a shout out to the folks from GluonHQ[3] who maintain and provide the Scene Builder tool free of charge. Lets help Gluon keep this tool free by testing, contributing or requesting for support or services at Gluon Services.[1]
Gluon Scene Builder
Finally, If you remember in part 1 I pointed out the hour hand shapes (arc & circle) having hard coded values for their angles and position attributes purely for prototyping purposes. In order to animate the arms around the clock face we will begin to make these values dynamic.
Before I show you the code, I want to show you the world clock face and its hour hand parts again. Just focus on the hour hand arc and hour hand tip which is a JavaFX Arc[3] and Circle[4] shape node respectively.
Parts of the hour hand of the world clock
An Arc shape is really a wedge (pizza slice). As we previously described the fill color is set to be transparent and the stroke width set to 4 pixels with a stroke color of orange. This gives it the appearence of a curved piece cut from a circle. Next, we will look at the Arc's attributes that will determine how long the arc will be and how to move it around the clock circle.
To change the length of the arc position around the clock face you will need to modify the following attributes of the JavaFXArc shape:
Attribute | Value | Description |
---|---|---|
startAngle | 0.0 | Start angle (in degrees). Zero is at the 3'o clock position moving counter clockwise |
length | 90.0 | Extent angle (in degrees). The angle offset from the start angle going counter clockwise |
Drawing the Hour Hand
Since the Arc shape is drawn in a counter clockwise rotation we have to do some math to make the arc appear in a clockwise direction. For example if it were moving from the 12:00 postion to the 3:00 position the start angle is 0° and the length (extent angle) would be 90° as shown below.
0 to 90 degrees in a Counter Clockwise direction
The hour hand has 12 positions and given a circle is 360° degrees (or 2π radians) each hour would be 360÷12 equalling 30° degrees. To represent 1:00 the hour hand arc should appear as a 30° (length) arc looking like its a moving in a clockwise direction from 12:00 to 1:00 when really its startAngle is 60° and length (extent angle) is 30°.
To make things a little easier let's look at a couple of simple math equations. These equations will later be converted to Java lambdas (functions).
The following is the formula to calculate the start angle based on the hour passed in:
degrees = ( 12 - hour ) * 30
// one hour is 30 degrees.startAngle = (degrees + 90) % 360
In the second equation you'll notice the 90 degrees added, this simulates the hour hand starting from the 12:00 o'clock position as opposed to the 3:00 position (which is zero degrees). Also, the modulus 360° is to ensure the angle between 0° to 359°.
The equation is translated to Java code as a lambda of typeFunction<Integer, Integer>
. The Function interface accepts a value and returns a value respectively. In this case thehour is passed in and thestart angle is calculated and returned.
/** * Start Angle of arc to draw the hour hand (start). */private Function<Integer, Integer> startAngleHour = ( hours ) -> { // 360 ÷ 12 = 30 degrees for each hours tick on the clock int degrees = (12 - hours) * 30; // add 90 degress to position start at the 12'o clock position. // JavaFX arc goes counter clockwise starting zero degrees at the 3 o'clock return (degrees + 90) % 360;};
The following code snippet is how to call the lambda function to calculate the startAngle:
int startAngle = startAngleHour.apply(1); // 60 degrees
After, creating a convenience function to calculate thestartAngle I also created a function to calculate thelength (extent angle) of the arc based on the hour of the clock (1-12).
The following is the formula to calculate the length (extent angle) based on the hour passed in:
degrees = ( 12 - hour ) * 30
extentAngle = (360 - degrees) % 360
As before the first formula is to determine degrees from the 12 o'clock position. The second formula is to move the arc to a start position by being subtracted from 360 (degrees).
The equation is translated to Java code as a lambda of typeFunction<Integer, Integer>
shown in the listing below:
/** * Extent angle of the arc to draw the hour hand (end) */private Function<Integer, Integer> extentAngleHour = ( hours ) -> { // 360 ÷ 12 = 30 degrees for each hours tick on the clock int degrees = (12 - hours) * 30; // make the extent angle counter clockwise to the 12'o clock position return (360 - degrees) % 360;};
With the lambda function (extentAngleHour) ready to be used, the following code statement illustrates how to invoke the function to calculate the extentAngle.
int extentAngle = extentAngleHour.apply(1); // 30 degrees
The following is an example of step-by-step calculations using the above equations to determine thestartAngle andextentAngle at 1:00, 2:00, and 3:00 o'clock.
Calculating Start and Length angles for Hour Hand Arc
Now that you know how to calculate and draw the arc now we need to get a reference to the JavaFX Arc and Circle nodes in order to update values dynamically.
If you remember in Scene Builder the nodes have their fx:id set with a name such ashourHandArc
andhourHandTip
. In the controller java file these variables will be defined using the FXML annotation as shown below:
@FXMLprivate Arc hourHandArc;@FXMLprivate Circle hourHandTip;
Using the above annotation (@FXML) is JavaFX's dependency injection mechanism to reference nodes in the scene graph. This allows the application to obtain instance objects such as theArc andCircle nodes to be injected (assigned) during runtime. This makes the nodes available to methods in the controller (WorldClockController.java) class.
After referencing the Arc the controller code can now update the positions on every clock tick as shown below.
// draw orange glowing hour hand arcint hourStartAngle = startAngleHour.apply(hour);int hourExtentAngle = extentAngleHour.apply(hour);hourHandArc.setStartAngle(hourStartAngle);hourHandArc.setLength(hourExtentAngle);
Similar to a time lapse an animation of the hour hand is shown below. It doesn't show the hour hand tip, more on that next.
Hour Hand Animation without the tip
Now that you know how to position and draw arcs to appear to move, let's look at basic trigonometry to move the hour hand tip around the clock face.
To change the (X, Y) position of the Circle shape around the clock face you will need to modify the following attributes of the JavaFXCircle shape:
Attribute | Value | Description |
---|---|---|
translateX | 35.0 | moves right 35 pixels |
translateY | 0.0 | moves zero pixels on the Y axis |
To move the hour hand tip (circle) in a clockwise direction I will be using Math's cosine and sine to determine on a unit circle its X, Y coordinate (point on the circle). Also, multiplying by the radius amount will project the point onto the hour hand track circle.
X * radius
andY * radius
respectively.Calculating the position of the tip:
/** * Positions the ball or tip at the start of the arc * The angle in degrees creating a point on the unit circle multiplied by the radius. */private BiFunction<Integer, Double, double[]> tipPointXY = ( angDegrees, radius ) -> { double [] pointXY = new double[2]; pointXY[0] = Math.cos(Math.toRadians(angDegrees)) * radius; pointXY[1] = Math.sin(Math.toRadians(angDegrees)) * radius; return pointXY;};
To use the function tipPointXY() it will return an array of type double containing two values wherehourTipPoint[0]
is the X coordinate andhourTipPoint[1]
is the Y coordinate respectively.
// draw orange glowing hour hand tip double [] hourTipPoint = tipPointXY.apply(hourStartAngle , 35.0); hourHandTip.setTranslateX(hourTipPoint[0]); hourHandTip.setTranslateY(hourTipPoint[1] * -1);
You should notice the method call tosetTranslateY(hourTipPoint[1] * -1)
where its value is multiplied by-1. This is to convert to the screen coordinate system where the Y coordinate going in a southerly direction are positive values.
Shown below is the hour handarc andtip moving around the clock face.
Hour Hand Animation with tip
To see the full listing of the code to move the clock arms see WorldClockController.java[6] on GitHub.
There you have it! A way to animate the clock face. InPart 3 of this blog series I will be creating a UI form to configure the world clock such as changing timezones and locations (I will finally remove my pesky hardcoded cities).
In Part 2, you got a chance to use some math and trig skills to determine how to position parts of the hour hand.
After learning how to convert the math to usable functions, you get a chance to see JavaFX's FXML annotations to reference nodes on the scene graph.
Lastly, you were able to see animations of the hour hand move about the clock face.
As always comments are welcome. Happy coding!
Don’t Forget to Share This Post!
Carl Dea is a Senior Developer Advocate at Azul. He has authored Java books and has been developing software for 20+ years with many clients, from Fortune 500 companies to nonprofit organizations. He has written software ranging from mission-critical applications to e-commerce applications. Carl has been using Java since the very beginning (when Applets were cool) and is a JavaFX enthusiast (fanboy) dating back to when it used to be called F3/JavaFX script. He greatly loves sharing and advocating Java based technologies.
Carl Dea is a Senior Developer Advocate at Azul. He has authored Java books and has been developing software for 20+ years with many clients, from Fortune 500 companies to nonprofit organizations. He has written software ranging from mission-critical applications to e-commerce applications. Carl has been using Java since the very beginning (when Applets were cool) and is a JavaFX enthusiast (fanboy) dating back to when it used to be called F3/JavaFX script. He greatly loves sharing and advocating Java based technologies.
SummarizingTokenWindowChatMemory: Enhancing LLM’s Conversations with Efficient Summarization
What Happens When 10,000 JVMs Collaborate in One Production Environment
BoxLang v1.6.0 – Performance, AI-Powered Docs, and Advanced Async Monitoring
Preparing for Spring Framework 7 and Spring Boot 4
Understanding MCP Through Raw STDIO Communication
Here’s Java 25, Ready to Perform to the Limit
A Dissection of Java JDBC to PostgreSQL Connections
Keywords Meet Vectors: Hybrid Search on MongoDB
Managing Distributed Applications in Kubernetes Using Cilium and Istio with Helm and Operator for Deployment
🧱 Monolith or 🧩 Microservices in 2025?
JC-AI Newsletter #6
Preparing for Spring Framework 7 and Spring Boot 4
Design Patterns Update to JDK25
SummarizingTokenWindowChatMemory: Enhancing LLM’s Conversations with Efficient Summarization
Understanding MCP Through Raw STDIO Communication
Here’s Java 25, Ready to Perform to the Limit
🧱 Monolith or 🧩 Microservices in 2025?
Java 23 Has Arrived, And It Brings a Truckload of Changes
Agents Meet Databases: The Future of Agentic Architectures
Managing Distributed Applications in Kubernetes Using Cilium and Istio with Helm and Operator for Deployment
Indexing all of Wikipedia, on a laptop
Working with Multiple Carets in IntelliJ IDEA
Clean Shutdown of Spring Boot Applications
Java 17 on the Raspberry Pi
Project Panama for Newbies (Part 1)
How to Create Mobile Apps with JavaFX (Part 1)
Foojay Slack: bit.ly/join-foojay-slack
Beginning JavaFX Applications with IntelliJ IDE
SpringBoot 3.2 + CRaC
Debugging Java on the Command Line
Learn about a number of experiments that have been conducted with Apache Kafka performance on Azul Platform Prime, compared to vanilla OpenJDK. Roughly 40% improvements in performance, both throughput and latency, are achieved.
Azul Platform Core is the #1 Oracle Java alternative, offering OpenJDK support for more versions (including Java 6 & 7) and more configurations for the greatest business value and lowest TCO.
What do you know about the code changes that were just introduced into the codebase? When will you notice if something goes wrong?
This user guide provides a brief history of Java EE/Jakarta EE and a detailed overview of some of the specifications that will be updated in Jakarta EE 11.
Azul Platform Core is the #1 Oracle Java alternative, offering OpenJDK support for more versions (including Java 6 & 7) and more configurations for the greatest business value and lowest TCO.
Contact us to get your ad seen by thousands of users every day!
[email protected]With this new series of video interviews, I want to take you behind-the-scenes of some applications built using JavaFX.
Let’s talk about the JavaFX framework itself, but also about the libraries and applications that are built with it.
Table of Contents A Personal StoryAbout DMX512 and OFLWhat is DMX512What is Open Fixture LibraryDMX512 Java LibraryMy Test SetupMinimal Code ExampleUsing Fixtures and ModesDetecting USB-to-DMX and IP-to-DMX interfacesDMX512 JavaFX Demo ProjectNext Steps In this post, I would like to inform …
Table of Contents CoreApplicationsGamesComponents, Libraries, ToolsPodcasts, Videos, BooksConferencesTutorialsMiscellaneousJFX Central Here is the overview of the JavaFX LinksOfTheMonth of June 2025. You can find the weekly lists on jfx-central.com. Did we miss anything? Is there anything you want to have included …
No comments yet. Be the first.