JavaFX 3D Shapes Example
This is a JavaFX 3D Shape example. Any shape, drawn in a three-dimensional space, having three dimensions (length, width, and depth) is known as a 3D shape.
JavaFX 8 offers two types of 3D shapes.
- Predefined shapes
- User-defined shapes
Box, Sphere, and Cylinder are three predefined 3D shapes that you can use in your JavaFX applications. You can also create any type of 3D shapes using a triangle mesh. The Box, Sphere, and Cylinder classes represent the three predefined shapes. The MeshView class represents a user-defined 3D shape in a Scene.
The following table shows an overview of the whole article:
Table Of Contents
The following examples uses Java SE 8 and JavaFX 2.2.
1. Using Predefined 3D Shapes
1.1 The Code
Fx3DShapeExample1.java
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.stage.Stage;
public class Fx3DShapeExample1 extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(Stage stage)
{
// Create a Box
Box box = new Box(100, 100, 100);
box.setTranslateX(150);
box.setTranslateY(0);
box.setTranslateZ(400);
// Create a Sphere
Sphere sphere = new Sphere(50);
sphere.setTranslateX(300);
sphere.setTranslateY(-5);
sphere.setTranslateZ(400);
// Create a Cylinder
Cylinder cylinder = new Cylinder(40, 120);
cylinder.setTranslateX(500);
cylinder.setTranslateY(-25);
cylinder.setTranslateZ(600);
// Create a Light
PointLight light = new PointLight();
light.setTranslateX(350);
light.setTranslateY(100);
light.setTranslateZ(300);
// Create a Camera to view the 3D Shapes
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(-50);
camera.setTranslateZ(300);
// Add the Shapes and the Light to the Group
Group root = new Group(box, sphere, cylinder, light);
// Create a Scene with depth buffer enabled
Scene scene = new Scene(root, 400, 200, true);
// Add the Camera to the Scene
scene.setCamera(camera);
// Add the Scene to the Stage
stage.setScene(scene);
// Set the Title of the Stage
stage.setTitle("An Example with Predefined 3D Shapes");
// Display the Stage
stage.show();
}
}
1.2 Introduction
JavaFX 8 provides the following three built-in 3D geometric shapes:
- Box
- Sphere
- Cylinder
The shapes are represented by instances of the Box, Sphere, and Cylinder classes. The classes inherit from the Shape3D class, which contains three properties that are common to all types of 3D shapes:
- Material
- Draw mode
- Cull face
The properties specific to a shape type are defined in the specific class defining the Shape. All shapes are nodes. Therefore, you can apply transformations to them. You can position them at any point in the 3D space using the translateX, translateY, and translateZ transformations.
1.3 The Box
A Box is defined by the following three properties:
- width
- height
- depth
The Box class contains two constructors:
- Box()
- Box(double width, double height, double depth)
The no-args constructor creates a Box with width, height, and depth of 2.0 each. The other constructor lets you specify the dimensions of the Box. The center of the Box is located at the origin of its local coordinate system.
The following snippet of code creates a Box with width 100, height 200 and depth 100. After the creation, the Box will be transformed.
// Create a Box Box box = new Box(100, 100, 100); box.setTranslateX(150); box.setTranslateY(0); box.setTranslateZ(400);
1.4 The Sphere
A Sphere is defined by only one property named radius. The Sphere class contains three constructors:
- Sphere()
- Sphere(double radius)
- Sphere(double radius, int divisions)
The no-args constructor creates a Sphere of radius 1.0. The second constructor lets you specify the radius of the Sphere. The third constructor lets you specify the radius and divisions. A 3D sphere is made up of many divisions, which are constructed from connected triangles. The value of the number of divisions defines the resolution of the Sphere. The higher the number of divisions, the smoother the Sphere looks.
The following snippet of code creates a Sphere with radius 50. After the creation, the Spere will be transformed.
// Create a Sphere Sphere sphere = new Sphere(50); sphere.setTranslateX(300); sphere.setTranslateY(-5); sphere.setTranslateZ(400);
1.5 The Cylinder
A Cylinder is defined by two properties:
- radius
- height
The radius of the Cylinder is measured on the XZ plane. The axis of the Cylinder is measured along the y-axis. The height of the Cylinder is measured along its axis. The Cylinder class contains three constructors:
- Cylinder()
- Cylinder(double radius, double height)
- Cylinder(double radius, double height, int divisions)
The no-args constructor creates a Cylinder with a 1.0 radius and a 2.0 height. The second constructor lets you specify the radius and height properties. The third constructor lets you specify the number of divisions, which defines the resolution of the Cylinder. The higher the number of divisions, the smoother the Cylinder looks.
The following snippet of code creates a Cylinder with radius 40 and height 120. After the creation, the Cylinder will be transformed.
// Create a Cylinder Cylinder cylinder = new Cylinder(40, 120); cylinder.setTranslateX(500); cylinder.setTranslateY(-25); cylinder.setTranslateZ(600);
The details about the creation of PointLight and PerspectiveCamera will be discussed in the following chapters.
1.6 The GUI
The program creates the three shapes and positions them in the space. It creates a Light, which is an instance of the PointLight, and positions it in the space. The light is used to light the 3D shapes. All shapes and the light are added to a Group, which is added to the Scene. To view the shapes, you need to add a Camera to the Scene. The program adds a PerspectiveCamera to the Scene.
2. Specifying the Shape Material
2.1 The Code
Fx3DShapeExample2.java
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.stage.Stage;
public class Fx3DShapeExample2 extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(Stage stage)
{
// Create a Box
Box box = new Box(100, 100, 100);
box.setTranslateX(250);
box.setTranslateY(0);
box.setTranslateZ(400);
// Create the Material
PhongMaterial material = new PhongMaterial();
material.setDiffuseColor(Color.TAN);
// Set the material for the box
box.setMaterial(material);
// Create a Box with texture
Box textbox = new Box(100, 100, 100);
textbox.setTranslateX(450);
textbox.setTranslateY(50);
textbox.setTranslateZ(400);
// Create the Material
PhongMaterial textureMaterial = new PhongMaterial();
// Create the Image
Image image = new Image("file:/img/core-logo-java.jpg");
textureMaterial.setDiffuseColor(Color.BEIGE);
textureMaterial.setDiffuseMap(image);
// Set the material for the box
textbox.setMaterial(textureMaterial);
// Create a Light
PointLight light = new PointLight();
light.setTranslateX(250);
light.setTranslateY(100);
light.setTranslateZ(300);
// Create a Camera to view the 3D Shapes
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(200);
camera.setTranslateY(-50);
camera.setTranslateZ(300);
// Create the Group with both Boxes
Group root = new Group(box, textbox);
// Create a Scene with depth buffer enabled
Scene scene = new Scene(root, 400, 200, true);
// Add the Camera to the Scene
scene.setCamera(camera);
// Add the Scene to the Stage
stage.setScene(scene);
// Set the Title of the Stage
stage.setTitle("An Example with specified Material");
// Display the Stage
stage.show();
}
}
A Material is used for rendering the surface of shapes. You can specify the Material for the surface of 3D objects using the Material property, which is defined in the Shape3D class. The Material property is an instance of the abstract class Material. JavaFX provides the PhongMaterial class as the only concrete implementation of Material. The following properties are defined in the PhongMaterial class:
- diffuseColor
- diffuseMap
- specularColor
- specularMap
- selfIlluminationMap
- specularPower
- bumpMap
The PhongMaterial class contains three constructors:
- PhongMaterial()
- PhongMaterial(Color diffuseColor)
- PhongMaterial(Color diffuseColor, Image diffuseMap, Image specularMap, Image bumpMap, Image selfIlluminationMap)
The no-args constructor creates a PhongMaterial with the diffuse color as Color.WHITE. The other two constructors are used to create a PhongMaterial with the specified properties.
The following snippet of code creates a Box, creates a PhongMaterial with tan diffuse color, and sets the Material to the Box:
// Create a Box Box box = new Box(100, 100, 100); box.setTranslateX(250); box.setTranslateY(0); box.setTranslateZ(400); // Create the Material PhongMaterial material = new PhongMaterial(); material.setDiffuseColor(Color.TAN); // Set the material for the box box.setMaterial(material);
In the second case, we use an Image as the diffuse map to have texture for the Material, as shown in the following code:
// Create a Box with texture
Box textbox = new Box(100, 100, 100);
textbox.setTranslateX(450);
textbox.setTranslateY(50);
textbox.setTranslateZ(400);
// Create the Material
PhongMaterial textureMaterial = new PhongMaterial();
// Create the Image
Image image = new Image("file:/img/core-logo-java.jpg");
textureMaterial.setDiffuseColor(Color.BEIGE);
textureMaterial.setDiffuseMap(image);
// Set the material for the box
textbox.setMaterial(textureMaterial);
2.2 The GUI
The following example shows two boxes. One Box with diffuse color and the other Box with diffuse map. The Image used for the diffuse map provides the texture for the surface of the second Box.

3. Specifying the Draw Mode of Shapes
3.1 The Code
Fx3DShapeExample3.java
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.DrawMode;
import javafx.scene.shape.Sphere;
import javafx.stage.Stage;
public class Fx3DShapeExample3 extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(Stage stage)
{
// Create a Box
Box box = new Box(100, 100, 100);
box.setDrawMode(DrawMode.LINE);
box.setTranslateX(150);
box.setTranslateY(0);
box.setTranslateZ(400);
// Create a Sphere
Sphere sphere = new Sphere(50, 20);
sphere.setDrawMode(DrawMode.LINE);
sphere.setTranslateX(300);
sphere.setTranslateY(-5);
sphere.setTranslateZ(400);
// Create a Cylinder
Cylinder cylinder = new Cylinder(40, 120, 5);
cylinder.setDrawMode(DrawMode.LINE);
cylinder.setTranslateX(500);
cylinder.setTranslateY(-25);
cylinder.setTranslateZ(600);
// Create a Light
PointLight light = new PointLight();
light.setTranslateX(350);
light.setTranslateY(100);
light.setTranslateZ(300);
// Create a Camera to view the 3D Shapes
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(-50);
camera.setTranslateZ(300);
// Add the Shapes and the Light to the Group
Group root = new Group(box, sphere, cylinder, light);
// Create a Scene with depth buffer enabled
Scene scene = new Scene(root, 400, 200, true);
// Add the Camera to the Scene
scene.setCamera(camera);
// Add the Scene to the Stage
stage.setScene(scene);
// Set the Title of the Stage
stage.setTitle("An Example with specified Draw Mode");
// Display the Stage
stage.show();
}
}
A 3D Shape surface consists of many connected polygons made up of triangles. For example, a Box is made up of 12 triangles. Each side of the Box using two triangles. The drawMode property in the Shape3D class specifies how the surface of 3D shapes is rendered. Its value is one of the constants of the DrawMode enum.
- DrawMode.FILL
- DrawMode.LINE
The DrawMode.FILL is the default and it fills the interior of the triangles. The DrawMode.LINE draws only the outline of the triangles. That is, it draws only lines connecting the vertices of the consecutive triangles.
The following code snippet creates a Box, a Sphere and a Cylinder with DrawMode.LINE:
// Create a Box Box box = new Box(100, 100, 100); box.setDrawMode(DrawMode.LINE); box.setTranslateX(150); box.setTranslateY(0); box.setTranslateZ(400); // Create a Sphere Sphere sphere = new Sphere(50, 20); sphere.setDrawMode(DrawMode.LINE); sphere.setTranslateX(300); sphere.setTranslateY(-5); sphere.setTranslateZ(400); // Create a Cylinder Cylinder cylinder = new Cylinder(40, 120, 5); cylinder.setDrawMode(DrawMode.LINE); cylinder.setTranslateX(500); cylinder.setTranslateY(-25); cylinder.setTranslateZ(600);
3.2 The GUI
The following GUI shows the shapes. The program output is similar to the one shown in the above example. The program sets the drawMode property of all shapes to DrawMode.LINE.

4. Using Cameras and Light Sources
4.1 The Code
Fx3DShapeExample4.java
import javafx.animation.Animation;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.shape.CullFace;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Fx3DShapeExample4 extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(Stage stage)
{
// Create a Box
Box box = new Box(100, 100, 100);
box.setCullFace(CullFace.NONE);
box.setTranslateX(250);
box.setTranslateY(100);
box.setTranslateZ(400);
// Create a Camera to view the 3D Shapes
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(-50);
camera.setTranslateZ(300);
// Add a Rotation Animation to the Camera
RotateTransition rotation = new RotateTransition(Duration.seconds(2), camera);
rotation.setCycleCount(Animation.INDEFINITE);
rotation.setFromAngle(0);
rotation.setToAngle(90);
rotation.setAutoReverse(true);
rotation.setAxis(Rotate.X_AXIS);
rotation.play();
// Create a red Light
PointLight redLight = new PointLight();
redLight.setColor(Color.RED);
redLight.setTranslateX(250);
redLight.setTranslateY(-100);
redLight.setTranslateZ(250);
// Create a green Light
PointLight greenLight = new PointLight();
greenLight.setColor(Color.GREEN);
greenLight.setTranslateX(250);
greenLight.setTranslateY(300);
greenLight.setTranslateZ(300);
// Add the Box and the Lights to the Group
Group root = new Group(box, redLight, greenLight);
// Enable Rotation for the Group
root.setRotationAxis(Rotate.X_AXIS);
root.setRotate(30);
// Create a Scene with depth buffer enabled
Scene scene = new Scene(root, 300, 400, true);
// Add the Camera to the Scene
scene.setCamera(camera);
// Add the Scene to the Stage
stage.setScene(scene);
// Set the Title of the Stage
stage.setTitle("An Example with a Camera");
// Display the Stage
stage.show();
}
}
4.2 Using Cameras
Cameras are used to render the Scene. Two types of cameras are available.
- Perspective camera
- Parallel camera
The names of the cameras suggest the projection type they use to render the Scene. A Camera in JavaFX is a node. They can be added to the scene graph and positioned like other nodes.
A PerspectiveCamera defines the viewing volume for a perspective projection, which is a truncated right pyramid. The Camera projects the objects contained within the near and far clipping planes onto the projection plane. Therefore, any objects outside the clipping planes are not visible.
The content that the camera will project onto the projection plane is defined by two properties in the Camera class.
- nearClip
- farClip
The nearClip is the distance between the Camera and the near clipping plane. Objects closer to the Camera than the nearClip are not rendered.
The farClip is the distance between the Camera and the far clipping plane. Objects farther from the Camera than the farClip are not rendered.
The PerspectiveCamera class contains two constructors.
- PerspectiveCamera()
- PerspectiveCamera(boolean fixedEyeAtCameraZero)
The no-args constructor creates a PerspectiveCamera with the fixedEyeAtCameraZero flag set to false, which makes it behave more or less like a parallel camera where the objects in the scene at Z=0 stay the same size when the scene is resized.
The second constructor lets you specify this flag. If you want to view 3D objects with real 3D effects, you need to set this flag to true. Setting this flag to true will adjust the size of the projected images of the 3D objects as the Scene is resized. Making the scene smaller will make the objects look smaller as well.
The following code snippet creates a PerspectiveCamera and adds it to the Scene:
// Create a Camera to view the 3D Shapes PerspectiveCamera camera = new PerspectiveCamera(false); camera.setTranslateX(100); camera.setTranslateY(-50); camera.setTranslateZ(300); // Add the Camera to the Scene scene.setCamera(camera);
You can move and rotate the Camera as you move and rotate nodes. To move it to a different position, use the translateX, translateY, and translateZ properties. To rotate, use the Rotate transformation.
In the following code snippet, the Group will be created and rotated along the X-Axis:
// Add the Box and the Lights to the Group Group root = new Group(box, redLight, greenLight); // Enable Rotation for the Group root.setRotationAxis(Rotate.X_AXIS); root.setRotate(30);






