The JavaFX Transformation support enables you to transform (translate, rotate, scale, shear) JavaFX nodes attached to the JavaFX scene graph. In this JavaFX Transformation tutorial I will take a closer look at how transformations work in JavaFX.

JavaFX Transformation Example

Here is a full JavaFX Transformation example to show you how JavaFX Transformations work:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Transform;
import javafx.stage.Stage;

public class TransformationsExample extends Application {

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

    public void start(Stage primaryStage) {

        Rectangle rectangle = new Rectangle();
        rectangle.setX(200);
        rectangle.setY(200);
        rectangle.setWidth(300);
        rectangle.setHeight(400);
        rectangle.setStroke(Color.TRANSPARENT);
        rectangle.setFill(Color.valueOf("#00ffff"));

        double degrees = 30;
        double rotationPointX = 100;
        double rotationPointY = 100;
        Transform rotate = Transform.rotate(degrees, rotationPointX, rotationPointY);
        rectangle.getTransforms().add(rotate);

        Transform translate = Transform.translate(100, 0);
        rectangle.getTransforms().add(translate);

        Pane pane = new Pane();
        pane.getChildren().add(rectangle);

        Scene scene = new Scene(pane, 1024, 800, true);
        primaryStage.setScene(scene);
        primaryStage.setTitle("2D Example");

        primaryStage.show();
    }
}

Transformation Objects

A JavaFX transformation is represented by a Transformation object of some kind. The JavaFX Transform class, javafx.scene.transform.Transform contains a few factory methods you can use to create instances of the Transform class. Here is an example:

Transform translate = Transform.translate(100, 0);

There are also some transformation classes you can use instead of the Transform factory methods. I will cover some of those in the following sections.

Add a Transformation to a JavaFX Control

You add a transformation to a JavaFX control by adding a Transform instance to the control via the this operation:

control.getTransforms().add(transformationObject);

Built-in Transformations

JavaFX comes with a set of built-in transformations you can use. These transformations are:

  • Translate
  • Rotate
  • Scale
  • Skew

I will explain some of these transformations in the following sections.

Translate Transformation

The JavaFX Translate Transformation will "move" a JavaFX Node from its pre-transformation position to a new position. You can translate a JavaFX Node along either the Y or X axis. The amount you translate the Node along these axes is the distance it is moved. Here is an example of translating a JavaFX ImageView :

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class TranslateTransformationExample extends Application {

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

    public void start(Stage primaryStage) {

        ImageView imageViewOriginal  = createImageView();
        ImageView imageViewTranslated = createImageView();

        Translate translateTransform = new Translate();
        translateTransform.setX(200);
        translateTransform.setY(100);

        imageViewTranslated.getTransforms().add(translateTransform);

        Pane pane = new Pane();
        pane.getChildren().add(imageViewTranslated);
        pane.getChildren().add(imageViewOriginal);

        Scene scene = new Scene(pane, 1024, 800, true);
        primaryStage.setScene(scene);
        primaryStage.setTitle("2D Example");

        primaryStage.show();
    }

    private ImageView createImageView() {
        FileInputStream input = null;
        try {
            input = new FileInputStream("assets/media/abstract-5719221_640.jpg");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Image image = new Image(input);
        ImageView imageView = new ImageView(image);
        return imageView;
    }

}

This example shows 2 ImageView nodes with a pre-transformation position of 0,0 - meaning on top of each other. After the translation you can see the translated ImageView under the non-transformed ImageView. The resulting app will look similar to this:

JavaFX translate transformation screenshot

Rotate Transformation

The JavaFX Rotate Transformation rotates a JavaFX Node around a pivot point. Here is a JavaFX rotate transformation example showing a rotated and a non-rotated ImageView:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class RotateTransformationExample extends Application {

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

    public void start(Stage primaryStage) {

        ImageView imageViewOriginal  = createImageView();
        ImageView imageViewTranslated = createImageView();

        Rotate rotateTransform = new Rotate();
        rotateTransform.setAngle(45);
        rotateTransform.setPivotX(0);
        rotateTransform.setPivotY(0);

        imageViewTranslated.getTransforms().add(rotateTransform);

        Pane pane = new Pane();
        pane.getChildren().add(imageViewTranslated);
        pane.getChildren().add(imageViewOriginal);

        Scene scene = new Scene(pane, 1024, 800, true);
        primaryStage.setScene(scene);
        primaryStage.setTitle("2D Example");

        primaryStage.show();
    }

    private ImageView createImageView() {
        FileInputStream input = null;
        try {
            input = new FileInputStream("assets/media/abstract-5719221_640.jpg");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Image image = new Image(input);
        ImageView imageView = new ImageView(image);
        return imageView;
    }

}

This is how the resulting app will look like:

JavaFX rotate transformation screenshot

Scale Transformation

The JavaFX Scale Transformation scales a JavaFX Node up or down compared to its natural size. A scale of 1.0 is the same as the natural size. A scale below 1.0 is smaller than the natural size. A scale above 1.0 is larger than the natural size. For instance, a scale of 0.5 horizontally means a scale to half of the natural size. A scale of 2.0 means a scale to double the size. Here is a JavaFX scale transformation example showing a JavaFX ImageView that is scaled up to 1.5 it's original size horizontally (X-axis), and scaled down to 0.5 its original size vertically (Y-axis):

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ScaleTransformationExample extends Application {

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

    public void start(Stage primaryStage) {

        ImageView imageViewOriginal = createImageView();
        ImageView imageViewScaled   = createImageView();

        Scale scaleTransformation = new Scale();
        scaleTransformation.setX(1.5);
        scaleTransformation.setY(0.5);
        scaleTransformation.setPivotX(0);
        scaleTransformation.setPivotY(0);

        imageViewScaled.getTransforms().add(scaleTransformation);

        Pane pane = new Pane();
        pane.getChildren().add(imageViewScaled);
        pane.getChildren().add(imageViewOriginal);

        Scene scene = new Scene(pane, 1024, 800, true);
        primaryStage.setScene(scene);
        primaryStage.setTitle("2D Example");

        primaryStage.show();
    }

    private ImageView createImageView() {
        FileInputStream input = null;
        try {
            input = new FileInputStream("assets/media/abstract-5719221_640.jpg");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Image image = new Image(input);
        ImageView imageView = new ImageView(image);
        return imageView;
    }

}

The resulting JavaFX app will look somewhat like this:

JavaFX scale transformation screenshot