Documentation



JavaFX: Working with JavaFX Graphics

8 Building a 3D Sample Application

This chapter provides the steps to build a simple application, MoleculeSampleApp, that uses some of the JavaFX 3D graphic features that were discussed earlier in this document.

The steps in this tutorial chapter use the NetBeans 7.4 IDE to help you develop the MoleculseSampleApp application.

The following file and appendix sections are included for this tutorial:

This chapter contains the following sections.

Prepare for this Tutorial

Use the following requirement and recommendation before continuing with this tutorial:

  1. (Required) Ensure that your system meets the system requirements listed in the Certified System Configurations page, which is linked from the Java SE download page at http://www.oracle.com/technetwork/java/javase/downloads/.

    The JavaFX Graphics Support section provides a list of graphics cards that support the JavaFX 3D feature. A supported graphics card is required to successfully run the finished JavaFX 3D sample application you build in this tutorial.

  2. (Recommended) Download and install NetBeans IDE 7.4. It is used in this tutorial to build the JavaFX 3D sample application.

Create the Project

Use NetBeans IDE 7.4 and the following steps to create the MoleculeSampleApp JavaFX project.

  1. From the NetBeans IDE File menu, choose New Project.

  2. In the New Project wizard, choose the JavaFX application category and JavaFX Application project. Click Next.

  3. Type MoleculeSampleApp for the Project Name. Enter the path for the Path Location text field or click Browse to navigate to the folder you want to use for this project.

  4. Click Finish.

    When you create a JavaFX project, NetBeans IDE provides a Hello World source code template as a starting point. You will replace that template source code in the next sections.

Create the Scene

Create the scene that will hold your molecule UI layout.

  1. First, copy the contents of Xform.java and save it to a file Xform.java file in the moleculesampleapp source folder of the moleculesampleapp project.

    This file contains the source code for the Xform sub-class that is derived from the Group class. Using the Xform node prevents the automatic recalculation of the position of a group node's pivot when the children of the group node is changed in a 3D UI layout. The Xform node allows you to add your own types of transforms and rotation. The file contains a translation component, three rotation components, and a scale component. Having the three rotation components is helpful when changing rotation values frequently, such as in changing the angle of the camera in the scene.

  2. If not already opened in the IDE editor, open the MoleculeSampleApp.java file that was created with the project creation. Replace the import statements at the top of the file with the import statements shown in Example 8-1.

    Example 8-1 Replacement Import Statements

    import javafx.application.Application;
    import javafx.scene.*;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
  3. Replace the rest of the body of the code in MoleculeSampleApp.java with the lines of code shown in Example 8-2. The code creates a new scene graph with an Xform as its node.

    Example 8-2 Replacement Body of Code

    /**
     * MoleculeSampleApp
     */
    public class MoleculeSampleApp extends Application {
     
        final Group root = new Group();
        final Xform world = new Xform();
     
        @Override
        public void start(Stage primaryStage) {
     
            Scene scene = new Scene(root, 1024, 768, true);
            scene.setFill(Color.GREY);
     
            primaryStage.setTitle("Molecule Sample Application");
            primaryStage.setScene(scene);
            primaryStage.show();
     
        }
     
        /**
         * The main() method is ignored in correctly deployed JavaFX 
         * application. main() serves only as fallback in case the 
         * application can not be launched through deployment artifacts, 
         * e.g., in IDEs with limited FX support. NetBeans ignores main().
         *
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    }
    
  4. Press Ctrl+S to save the file.

Set Up the Camera

Set up the camera in a hierarchy of Group class with Xform instances. Perform the translation and rotation on the camera to change its default location.

  1. Add the following lines of code, shown in bold below, so that they appear after the declaration statement for the world object, as shown in Example 8-3.

    These lines of code create an instance of a perspectiveCamera and three instances of the public class Xform, which extends the Group class. The Xform class is defined in the Xform.java file you added to your NetBeans project in the previous section of this document.

    Example 8-3 Add Variables for the Camera

    final Group root = new Group();
        final Xform world = new Xform();
        final PerspectiveCamera camera = new PerspectiveCamera(true);
        final Xform cameraXform = new Xform();
        final Xform cameraXform2 = new Xform();
        final Xform cameraXform3 = new Xform();
        private static final double CAMERA_INITIAL_DISTANCE = -450;
        private static final double CAMERA_INITIAL_X_ANGLE = 70.0;
        private static final double CAMERA_INITIAL_Y_ANGLE = 320.0;
        private static final double CAMERA_NEAR_CLIP = 0.1;
        private static final double CAMERA_FAR_CLIP = 10000.0;
        
    
  2. Copy the lines of code for the buildCamera() method, shown in Example 8-4. Add them right after the lines for variable declarations.

    The buildCamera() method sets the camera to have the view upside down instead of the default JavaFX 2D Y-down. So the scene is viewed as a Y-up (Y-axis pointing up) scene.

    Example 8-4 Add the buildCamera() Method

    private void buildCamera() {
            root.getChildren().add(cameraXform);
            cameraXform.getChildren().add(cameraXform2);
            cameraXform2.getChildren().add(cameraXform3);
            cameraXform3.getChildren().add(camera);
            cameraXform3.setRotateZ(180.0);
     
            camera.setNearClip(CAMERA_NEAR_CLIP);
            camera.setFarClip(CAMERA_FAR_CLIP);
            camera.setTranslateZ(CAMERA_INITIAL_DISTANCE);
            cameraXform.ry.setAngle(CAMERA_INITIAL_Y_ANGLE);
            cameraXform.rx.setAngle(CAMERA_INITIAL_X_ANGLE);
        }
    
  3. In the start() method, add the call to the buildCamera() so that it appears as shown in bold in Example 8-5

    Example 8-5 Add Method Call to buildCamera()

    public void start(Stage primaryStage) {
    
            buildCamera();
            
    
  4. Set the camera in the scene by copying the line of code shown in bold in Example 8-6 and adding it to the end of the start() method.

    Example 8-6 Set the Camera in the Scene

    primaryStage.show();
            scene.setCamera(camera);
    
  5. Save the file with Ctrl+S.

Build the Axes

Add the 3D axes that you will use to build this molecule. The Box class is used to create the axes and the PhongMaterial is used to set the specular and diffused colors. By default in JavaFX, the Y-axis is down.

Per the usual convention, the X-axis is shown in the color red, Y-axis is shown in green, and Z-axis in blue.

  1. Add the following import statements shown in Example 8-7 to the top of the source file.

    Example 8-7 Add Two Additional Import Statements

    import javafx.scene.paint.PhongMaterial;
    import javafx.scene.shape.Box;
    
  2. Add the following variable declaration statement, shown in Example 8-8.

    Example 8-8 Add a Variable for the Axes

    private static final double AXIS_LENGTH = 250.0;
    
  3. Copy the following declaration shown in bold in Example 8-9 and add it to just after the line where root is declared.

    Example 8-9 Create the axisGroup

    final Group root = new Group();
    final Xform axisGroup = new Xform();
    
  4. Add the buildAxes() method shown in Example 8-10 to after the buildCamera() method.

    Example 8-10 Add buildAxes() Method

    private void buildAxes() {
            final PhongMaterial redMaterial = new PhongMaterial();
            redMaterial.setDiffuseColor(Color.DARKRED);
            redMaterial.setSpecularColor(Color.RED);
     
            final PhongMaterial greenMaterial = new PhongMaterial();
            greenMaterial.setDiffuseColor(Color.DARKGREEN);
            greenMaterial.setSpecularColor(Color.GREEN);
     
            final PhongMaterial blueMaterial = new PhongMaterial();
            blueMaterial.setDiffuseColor(Color.DARKBLUE);
            blueMaterial.setSpecularColor(Color.BLUE);
     
            final Box xAxis = new Box(AXIS_LENGTH, 1, 1);
            final Box yAxis = new Box(1, AXIS_LENGTH, 1);
            final Box zAxis = new Box(1, 1, AXIS_LENGTH);
            
            xAxis.setMaterial(redMaterial);
            yAxis.setMaterial(greenMaterial);
            zAxis.setMaterial(blueMaterial);
     
            axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
            axisGroup.setVisible(true);
            world.getChildren().addAll(axisGroup);
        }
    
  5. Add the call to buildAxes() method, as shown in bold in Example 8-11.

    Example 8-11 Add Call to buildAxes() Method

    buildCamera();
            buildAxes();
    
  6. Compile and run the project by right-clicking the MoleculeSampleApp node in the project window and choose Run. A window appears with the 3D axes, as shown in Figure 8-1.

Build the Molecule

In this section, you build the molecule UI. This is where you use the Xform class and 3D features, such as PhongMaterial, Sphere, and Cylinder. The Xform class is also used.

  1. To declare the moleculeGroup Xform, copy the line of code shown in bold in Example 8-12. Paste it after the axisGroup variable.

    Example 8-12 Declare the moleculeGroup Xform

    final Xform axisGroup = new Xform();
     final Xform moleculeGroup = new Xform();
    
  2. Add the following import statements for the classes used in the buildMolecule() method:

    Example 8-13 Add Import Statements for build Molecule()

    import javafx.scene.shape.Cylinder;
        import javafx.scene.shape.Sphere;
        import javafx.scene.transform.Rotate;
    
  3. Add the following statement, shown in bold, for the HYDROGEN_ANGLE variable used in the buildMolecule() method:

    Example 8-14 Add Import Statements for build Molecule()

    private static final double AXIS_LENGTH = 250.0;
        private static final double HYDROGEN_ANGLE = 104.5;
    
  4. Copy the body of code for the buildMolecule() method and paste it after the buildAxes() method in the MoleculeSampleApp.java file.

  5. In the start() method, add the call to the buildMolecule() method so that it appears as shown in bold in Example 8-15.

    Example 8-15 Add the Call to the buildMolecule() Method

    buildCamera();
    buildAxes();
    buildMolecule();
    
  6. Now run the project and you should see something similar to Figure 8-2.

    Figure 8-2 The Water Molecule 3DModel

    Description of Figure 8-2 follows
    Description of "Figure 8-2 The Water Molecule 3DModel"

  7. Turn off the visibility of the axes by modifying the visible property to false, as shown in Example 8-16. Run the MoleculeSampleApp again to see the running application without the axes shown.

    Example 8-16 Set visible Property to false

    axisGroup.setVisible(false);
    

Add Camera Viewing Controls

The handleMouse() and handleKeyboard() methods allow you to see the different camera views. The source has been provided for you to demonstrate the use of the mouse and the keyboard keys to manipulate the camera's view in the scene.

  1. Add the declaration for variables that are used in the handleMouse() and handleKeyboard() source code you are about to add. Copy the code shown in Example 8-17 and paste after the line for the HYDROGEN_ANGLE declaration.

    Example 8-17 Add Variables Used

    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;    private static final double TRACK_SPEED = 0.3;
            
        double mousePosX;
        double mousePosY;
        double mouseOldX;
        double mouseOldY;
        double mouseDeltaX;
        double mouseDeltaY;
    
  2. Copy the import statements used in the handleMouse() and handleKeyboard() methods, as shown in Example 8-18. Paste them at the top of the MoleculeSampleApp.java file.

    Example 8-18 Add the Import Statements

    import javafx.event.EventHandler;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.input.MouseEvent;
    
  3. Copy the lines of code for the handleMouse() and the handleKeyboard() methods from the 3D MoleculeSampleApp Code Appendix. Add them after the buildMolecule() method in the MoleculeSampleApp.java file.

  4. In the start() method, add the calls to the handleKeyboard() and handleMouse() methods that you just added. Copy the lines of code shown in bold in Example 8-19 and paste them after the scene.setFill(Color.GREY) line.

    Example 8-19 Add Method Calls

    Scene scene = new Scene(root, 1024, 768, true);
            scene.setFill(Color.GREY);
            handleKeyboard(scene, world);
            handleMouse(scene, world);
    
  5. Save the file.

  6. Compile and run the project. Use the following mouse or keyboard strokes to get the different views.

    • Hold the left mouse button and drag the mouse right or left and up or down to rotate the camera view of the model around the axes.

    • Hold the right mouse button and drag the mouse to the left to move camera view away from the model. Drag the mouse to the right to move the camera view closer to the molecule model.

    • Press Ctrl+Z to return the model to its initial position.

    • Press Ctrl+V to show and hide the molecule from view.

    • Press Ctrl+X to show and hide the axes.

Close Window

Table of Contents

JavaFX: Working with JavaFX Graphics

Expand | Collapse