Leon Atherton Leon is a developer at IDRsolutions and product manager for BuildVu. He is responsible for managing the BuildVu product strategy and roadmap, and also spends a lot of his time writing code to build new features, improve functionality, fix bugs, and improve the testing for BuildVu.

Setting AffineTransform and Font in FXML vs JavaFX

2 min read

JavaFX is well documented and has lots of examples in the API to help when writing your application, but as FXML is not Java there is unfortunately no such API and very few examples, which can make hand-coding FXML a little more tricky. I suspect the cause of this is that the number of use cases for hand coding FXML is low, and we are expected to use automated tools such as SceneBuilder.

IDEs are slowly catching up and NetBeans now offers FXML code completion to lend a hand, but unfortunately XML code completion is not as intuitive as for regular code, and it can be difficult to know what to start with, as I will show below.

Our use case is that we are converting PDF files into other formats, for example HTML5, SVG, JavaFX and FXML. As we are not doing this by hand, something like SceneBuilder is not an option – instead we must programmatically generate the HTML, SVG, JavaFX and FXML files.

As a baseline, here is the code to draw some text with an AffineTransform and Font set in JavaFX:

        Text text = new Text();
        text.setText("My Text!");
        text.setFill(Color.RED);
        text.getTransforms().add(Transform.affine(0.97, -0.19, 0.19, 0.97, 50, 50));
        text.setFont(Font.font("Arial", FontWeight.BOLD, FontPosture.ITALIC, 24));
        content.getChildren().add(text);

It is possible to do very similar in FXML, for example in the .FXML file you can have as little as this:

<Text fx:id="text" />

Which you are then able to access in the Controller Java class by declaring the Text like so:

    @FXML private Text text;

And then modifying in the initialize (or other method) like so:

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        text.setText("My Text!");
        text.setFill(Color.RED);
        text.getTransforms().add(Transform.affine(0.97, -0.19, 0.19, 0.97, 50, 50));
        text.setFont(Font.font("Arial", FontWeight.BOLD, FontPosture.ITALIC, 24));
    }

This works well, but is unfortunately not without problems. One of the reasons I am a fan of using FXML over JavaFX is that if you generate a large FXML file (for example if you are converting PDF to FXML where you have no control over how much of what is in the PDF), there is no compiler that will refuse to compile your class because a method exceeds the 64KB size limit.

It is possible to split the methods up and chain them together, but this is messy, especially when you need to stop halfway through declaring something long like paths of a shape, and you need to pass all your fields into the next method to continue adding.

The best option is to get as much as possible into the FXML file. Here is that same piece of text with everything declared inside the FXML file:

<Text text="My Text!" fill="#FF0000" fx:id="affineText">
<font>
<Font name="Arial Bold Italic" size="24" />
</font>
<transforms>
<javafx.scene.transform.Affine mxx="0.97" myx="-0.19" mxy="0.19" myy="0.97" tx="50" ty="50" />
</transforms>
</Text>

If you create a new FXML project in NetBeans and add the above to Sample.fxml, you will hopefully see the same as this screenshot:

fxml

There are some noticeable differences with the FXML version. For example the fill is set with a hex color, and the font weight and posture is set in the same string as the font name. It is also possible to add fill tags, and set the color like so:

<fill>
<javafx.scene.paint.Color red="1" green="0" blue="0" />
</fill>

It is important to note that things like the font and transform (and color) go inside their own tags within the Text tag, but in my simple example you will also see it’s possible to self close the tag.

In this example I have referenced the class in the tag for transform and color, but it is also possible to add imports for those classes like so, and use them without the class path:

<?import javafx.scene.paint.*?>
<?import javafx.scene.transform.*?>

Please do try out our PDF to JavaFX and FXML converter and let us know what you think. You can learn more about what else we do at IDR Solutions. What are your thoughts on FXML?

This post is part of our “SVG Article Index” in these articles, we aim to help you build knowledge and understand SVG.

IDRsolutions develop a Java PDF Viewer and SDK, an Adobe forms to HTML5 forms converter, a PDF to HTML5 converter and a Java ImageIO replacement. On the blog our team post anything interesting they learn about.

Leon Atherton Leon is a developer at IDRsolutions and product manager for BuildVu. He is responsible for managing the BuildVu product strategy and roadmap, and also spends a lot of his time writing code to build new features, improve functionality, fix bugs, and improve the testing for BuildVu.

Why you should care about Unicode support in Java…

Here at IDRsolutions we are very excited about Java 9 and have written a series of articles explaining some of the main features. In...
Bethan Palmer
1 min read

Updates on Java PDF Viewer roadmap from IDRsolutions

My previous blog post (5 changes we are considering in 2016 for IDRsolutions), generated lots of feedback for us (for which we would like...
Mark Stephens
58 sec read

My key takeaways from NetBeans Day 2015

NetBeans Day 2015 had to be rescheduled to bigger rooms because of attendee demand. It was a very busy schedule. Here are my notes...
Mark Stephens
2 min read

One Reply to “Setting AffineTransform and Font in FXML vs JavaFX”

Leave a Reply

Your email address will not be published. Required fields are marked *