I actually wanted to build a 2x2 rubiks cube. As the Box class in javafx doesn't provide the feature of building a cube with different colours on different faces, I chose to build the cubes using RectangleBuilder to build rectangles with different colours and then applied transformations to build the cubes. But while testing the code I saw that the entire display was coming in a broken manner with the edges overlapping as shown in the picture.
Here is my source code:
package helloworld; import javafx.scene.transform.Rotate; import javafx.scene.PerspectiveCamera; import javafx.scene.transform.Translate; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.SceneAntialiasing; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.shape.RectangleBuilder; import javafx.scene.transform.Rotate; import javafx.util.Duration; public class NewFXMain1 extends Application { public class Cube extends Group { final Rotate rx = new Rotate(0,Rotate.X_AXIS); final Rotate ry = new Rotate(0,Rotate.Y_AXIS); final Rotate rz = new Rotate(0,Rotate.Z_AXIS); public Cube(double size, Color back,Color bottom,Color right,Color left,Color top,Color front, double shade) { getTransforms().addAll(rz, ry, rx); getChildren().addAll( RectangleBuilder.create() // back face .width(size).height(size) .fill(back.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0)) .translateX(-0.5*size) .translateY(-0.5*size) .translateZ(0.5*size) .smooth(true) .stroke(Color.BLACK) .build(), RectangleBuilder.create() // bottom face .width(size).height(size) .fill(bottom.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0)) .translateX(-0.5*size) .translateY(0) .rotationAxis(Rotate.X_AXIS) .rotate(90) .smooth(true) .stroke(Color.BLACK) .build(), RectangleBuilder.create() // right face .width(size).height(size) .fill(right.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0)) .translateX(-1*size) .translateY(-0.5*size) .rotationAxis(Rotate.Y_AXIS) .rotate(90) .smooth(true) .stroke(Color.BLACK) .build(), RectangleBuilder.create() // left face .width(size).height(size) .fill(left.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0)) .translateX(0) .translateY(-0.5*size) .rotationAxis(Rotate.Y_AXIS) .rotate(90) .smooth(true) .stroke(Color.BLACK) .build(), RectangleBuilder.create() // top face .width(size).height(size) .fill(top.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0)) .translateX(-0.5*size) .translateY(-1*size) .rotationAxis(Rotate.X_AXIS) .rotate(90) .smooth(true) .stroke(Color.BLACK) .build(), RectangleBuilder.create() // front face .width(size).height(size) .fill(front) .translateX(-0.5*size) .translateY(-0.5*size) .translateZ(-0.5*size) .smooth(true) .stroke(Color.BLACK) .build() ); } } PerspectiveCamera camera = new PerspectiveCamera(true); @Override public void start(Stage primaryStage) throws Exception { Group root = new Group(); Scene scene=new Scene(root,600,600,true); camera.setNearClip(0.00001); camera.setFarClip(10000000.0); camera.getTransforms().addAll ( new Rotate(0, Rotate.Y_AXIS), new Rotate(0, Rotate.X_AXIS), new Translate(0, 0, -1000)); scene.setCamera(camera); Cube c1 = new Cube(50,Color.BLUE.darker(),Color.BLUE.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c1.setTranslateX(100); Cube c2 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c2.setTranslateX(50); Cube c3 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c3.setTranslateX(50); c3.setTranslateZ(50); Cube c4 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c4.setTranslateX(100); c4.setTranslateZ(50); Cube c5 = new Cube(50,Color.BLUE.darker(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c5.setTranslateX(100); c5.setTranslateY(50); Cube c6 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c6.setTranslateX(50); c6.setTranslateY(50); Cube c7 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c7.setTranslateX(50); c7.setTranslateZ(50); c7.setTranslateY(50); Cube c8 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1); c8.setTranslateX(100); c8.setTranslateZ(50); c8.setTranslateY(50); handleMouse(scene,root); Group k=new Group(c1,c2,c3,c4,c5,c6,c7,c8); root.getChildren().addAll(k); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } private static final double CONTROL_MULTIPLIER = 0.1; private static final double SHIFT_MULTIPLIER = 10.0; private static final double MOUSE_SPEED = 0.1; private static final double ROTATION_SPEED = 2.0; double mousePosX,mousePosY,mouseOldX,mouseOldY,mouseDeltaX,mouseDeltaY; private void handleMouse(Scene scene, final Node root) { scene.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent me) { mousePosX = me.getSceneX(); mousePosY = me.getSceneY(); mouseOldX = me.getSceneX(); mouseOldY = me.getSceneY(); } }); scene.setOnMouseDragged(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent me) { mouseOldX = mousePosX; mouseOldY = mousePosY; mousePosX = me.getSceneX(); mousePosY = me.getSceneY(); mouseDeltaX = (mousePosX - mouseOldX); mouseDeltaY = (mousePosY - mouseOldY); double modifier = 1.0; if (me.isControlDown()) { modifier = CONTROL_MULTIPLIER; } if (me.isShiftDown()) { modifier = SHIFT_MULTIPLIER; } if (me.isPrimaryButtonDown()) { camera.setRotationAxis(Rotate.Y_AXIS);camera.setRotate(camera.getRotate() - mouseDeltaX*modifier*ROTATION_SPEED); // camera.setRotationAxis(Rotate.X_AXIS);camera.setRotate(camera.getRotate() + mouseDeltaY*modifier*ROTATION_SPEED); // - } else if (me.isSecondaryButtonDown()) { double z = camera.getTranslateZ(); double newZ = z + mouseDeltaX*MOUSE_SPEED*modifier; camera.setTranslateZ(newZ); } } }); // setOnMouseDragged } //handleMouse }