The following article describes how to paint a dartboard with JavaFX. This article tries to describe how to use primitive shapes to paint a complex Scene with JavaFX. A side-effect is that you will learn how to use trigonometric functions like sine and cosine and place points at an arbitrary position on a circle. In the example, a Scene is created which contains some javafx.scene.shape.Circle objects, javafx.scene.shape.Arc objects and javafx.scene.shape.Path objects (with javafx.scene.shape.ArcTo, javafx.scene.shape.MoveTo and javafx.scene.shape.LineTo). The objects are created with the associated Builder classes (javafx.scene.shape.ArcBuilder, javafx.scene.shape.ArcToBuilder, javafx.scene.shape.CircleBuilder, javafx.scene.shape.PathBuilder. To display the numbers around the board the class javafx.scene.text.Text is used. The appearence of the dartboard can be adapted by changing the CSS file.
The following screenshots show the finished JavaFX application. Only by a changing the CSS file the style of the application looks like an electronic dartboard.
Create a Stage with a Scene and Pane and a radial gradient background color.
Paint the border around the Bull and the Bulls Eye with Circle objects.
Paint the Bull and the Bulls eye with two Arc objects.
Paint a single field of the dartboard with a Path and explain the usage of sine and cosine.
Place the fields of the dartboard at the correct position.
Paint the numbers around the board with Text objects.
In the first step we create a Stage with a Scene and a Pane with a radial gradient background color.
The constants FACTOR_SIZE and BORDER_SIZE will be used later to resize the dartboard. The basesize of the board is 400px.
In the next step we draw two yellow circles in the middle of the board. These circles are the border for the Bull and the Bulls Eye.
The constants CENTER_X and CENTER_Y define the middlepoint of the Scene. For the creation of a Circle a CircleBuilder is used. The created Circle is directly added to the root Pane of the application. The style for the border-line is read from the CSS file dartboard.css.
It is important to set -fx-fill: null because the default fill color ist black. If you want no fill color you must change it to the value null.
In this step the Bull and the Bulls eye is painted into the dartboard by using two Arc objects.
For the creation of the filled Circles is an ArcBuilder used. The created Arc is directly added to the root Pane of the application. The style for the bulls-eye-style and bull-style is read from the CSS file dartboard.css. To fill the Arcs with a color the stroke width is used. The function strokeWidth is called with the size of the Bull and Bulls Eye.
Note: To paint the Bull and the Bulls eye with its border an Arc and a Circle is used. The reason for that is, that I want to explain both classes. A simpler way is to use a Circle which is filled with a color.
Now we will create a method to paint one field into the dartboard using a Path. The important part of this step is to determine the four edges of the field you want to draw.
The following screenshot shows a very big dartboard field. It is placed between two circles. When you want to paint this field you have to determine the 4 points on the circles. For every point you need the x-coordinate and the y-coordinate.
We need the middlepoint CENTER_X, a radius and an angle. With these values it is possible to calculate the four points, which are necessary to paint the field.
Further information about a Circle can be found here.
To determine the first point (pointX1, pointY1) we need the innerRadius and the angleAlpha which is between the left purple line with the text innerRadius and the blue line in the middle. Also it is important to move the coordinate to the center of the Scence because the coordinate system has its origin in the left upper corner (CENTER_X, CENTER_Y).
The other points can be calculated in the same way. But you have to notice that the points on the right side need the angleAlphaNext.
With these informations we can create a function which calcutates the two angles and the four points. And use them to draw the field on the dartboard.
For the drawing we use a PathBuilder to create a Path. Important are the elements of the Path.
First, a kind of pencil is moved to point1 with the MoveTo element. Then a line is drawn to point2 with LineTo (orange arrow with number 1 figure above). At point2 an ArcTo element is needed to reach point3 (orange arrow with number 2 figure above). So we build this element with an ArcToBuilder. Important is the sweetFlag which indicates the direction of the Arc, i.e. if the Arc is above the imaginary line between point2 and point3. When point3 is reached a line is drawn to point4 with a LineTo element (orange arrow with number 3 figure above). At the end we paint an other Arc to the start point point1 with an ArcTo element (orange arrow with number 4 figure above). Please note that the sweepFlag is false now.
Note that the style for the dartboard fields are dymamic. The parameter style is used to change the styling of the fields.
With this method we are able to paint all dartboard fields.
Now we draw all dartboard fields into the dartboard. With the correct position and color.
First we divide the dartboard into 20 pies. Every pie has an angle of 18 degrees (360°/20=18°).
So we have to draw 20 pies where every pie has four fields. Please note that every pie needs an offset of 9° because the pie for the number 20 does not start with an angle of 0°. It starts with an offset of 9°.
For every pie four fields are created by calling the function createDartboardField. The styling of the fields is done with the variables doubleTripleStyle and fieldStyle. These variables use values which are defined in the CSS file.
The last step is placing the numbers around the dartboard.
First the numbers and the font size are defined at the top of the class.
"11", "14", "9", "12", "5"
After that we implement a function paintNumbers which places Text objects around the dartboard.
The approach to determine the coordinates for the number is the same like calculating the coordinates for the dartboard fields. You need an angleAlpha which is used to calculate pointX1 and pointY1. These coordinates are used to place the Text object which is created with a TextBuilder.
* at the correct x position on the board.
* at the correct y position on the board.
If you want to test the function paintNumbers you have to add the method call in the method start.
Here you find the complete CSS file for the dartboard application.
Simply change the colors and increase the stroke-width of the borders.
For this animation I used a Timeline. I described how to use a Timeline in the article JavaFX - Animation of Circles with a Timeline.