Setting AffineTransform and Font in FXML vs JavaFX

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 PDF help.org. 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.

The following two tabs change content below.
Leon is a Developer at IDRsolutions, focusing mainly on development of the PDF to HTML5/SVG converter. He was a speaker at JavaOne 2012, co-presenting a session titled 'Lessons Learned in Writing a PDF-to-JavaFX Converter for NetBeans'.

Related Posts:

Leon Atherton

About Leon Atherton

Leon is a Developer at IDRsolutions, focusing mainly on development of the PDF to HTML5/SVG converter. He was a speaker at JavaOne 2012, co-presenting a session titled 'Lessons Learned in Writing a PDF-to-JavaFX Converter for NetBeans'.

One thought on “Setting AffineTransform and Font in FXML vs JavaFX

  1. For the color you can use the Color-constants in the fxml-file RED would work and fill=”RED” does so too.

Leave a Reply

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

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>