Mastering JavaFX 10
上QQ阅读APP看书,第一时间看更新

Transformations

JavaFX API supports basic transformations for every Node (and Shape, which extends Node).

Three basic transformations can be used through Node methods:

  • setRotate (double angle): Rotates around the center of the Node
  • setTranslateX (double pixels), setTranslateY (double pixels): Shifts the Node by a set amount of pixels
  • setScaleX (double scale), setScaleY (double scale): Increases (or decreases) the Node by multiplying its horizontal or vertical dimensions by scale

For more complex transformations, the Transform class can be used. It allows us to work precisely with every parameter of the transformation. For example, you can concatenate two transformations into one combined and use two different nodes to save.

Note that through Transform, there are usually more options available. For example, the setRotate() method always uses the center of the shape as a pivot point, whereas for the rotate transformation you can set a deliberate pivot point inside the shape:

 Rotate rotateTransform = new Rotate();
rotateTransform.setAngle(45);
rotateTransform.setPivotX(10);
rotateTransform.setPivotY(10);
node.getTransforms().add(rotateTransform);

The following demo shows rotate, translate, scale, and shear transforms. Additionally, there is a fifth transformation that is a combination of shear and rotate. On the following figure, the black border is an original rectangle and the gray shape is the transformed one:

The code for the preceding figure is a bit long because of the double rectangle functionality; the actual transformations are at the end. Take a look at the following code snippet:

// chapter2/other/Transformations.java
public class Transformations extends Application {

// service method to make similar rectangles
private Rectangle addRect() {
// here we create two rectangles:
// one for transformation
Rectangle rect = new Rectangle(20, 100, Color.DARKGRAY);
// and another to demonstrate original
// untransformed rectangle bounds
Rectangle rectOrig = new Rectangle(20, 100);
rectOrig.setFill(Color.TRANSPARENT);
rectOrig.setStroke(Color.BLACK);

StackPane pane = new StackPane(rect, rectOrig);
root.getChildren().add(pane);

return rect;
}

TilePane root = new TilePane(50,50);

@Override
public void start(Stage primaryStage) {
// rotate transformation
Rectangle rect1 = addRect();
rect1.setRotate(30);

// translate transformation
Rectangle rect2 = addRect();
rect2.setTranslateY(20);

// scale transformation
Rectangle rect3 = addRect();
rect3.setScaleX(2);

// shear transformation
Rectangle rect4 = addRect();
rect4.getTransforms().add(new Shear(0.3, 0));

// combining two transformations
Rectangle rect5 = addRect();
Transform t1 = new Shear(0.3, 0);
Transform t2 = new Rotate(-15);
rect5.getTransforms().add(t1.createConcatenation(t2));

// adding all transformed rectangles to the scene
root.setPadding(new Insets(50));
primaryStage.setTitle("Hello World!");
primaryStage.setScene(new Scene(root, 500, 250));
primaryStage.show();
}
}