文档



JavaFX:使用JavaFX图形
8 构建一个3D示例应用程序(版本8)

8 构建一个3D示例应用程序

本章提供构建一个简单应用程序MoleculeSampleApp的步骤,该应用程序使用了之前在本文档中讨论的一些JavaFX 3D图形特性。

本教程章节中的步骤使用NetBeans 7.4 IDE来帮助您开发MoleculeSampleApp应用程序。

本教程包含以下文件和附录部分:

本章包含以下部分。

准备本教程

在继续本教程之前,请使用以下要求和建议:

  1. (必需)确保您的系统符合认证系统配置页面中列出的系统要求,该页面链接在Java SE下载页面上,网址为http://www.oracle.com/technetwork/java/javase/downloads/

    JavaFX图形支持部分提供了支持JavaFX 3D功能的图形卡列表。为了成功运行您在本教程中构建的JavaFX 3D示例应用程序,需要支持的图形卡。

  2. (推荐) 下载并安装NetBeans IDE 7.4。本教程中使用它来构建JavaFX 3D示例应用程序。

创建项目

使用NetBeans IDE 7.4和以下步骤创建MoleculeSampleApp JavaFX项目。

  1. 从NetBeans IDE的文件菜单中选择新建项目

  2. 在新建项目向导中,选择JavaFX应用程序类别和JavaFX应用程序项目。点击下一步

  3. 为项目名称输入MoleculeSampleApp。在路径位置文本框中输入路径,或点击浏览按钮导航到要用于此项目的文件夹。

  4. 点击完成

    创建JavaFX项目时,NetBeans IDE会提供一个Hello World源代码模板作为起点。您将在下一节中替换该模板源代码。

创建场景

创建一个用于容纳分子UI布局的场景。

  1. 首先,复制Xform.java的内容,并将其保存到Xform.java文件中,该文件位于moleculesampleapp项目的moleculesampleapp源文件夹中。

    该文件包含了从Group类派生的Xform子类的源代码。使用Xform节点可以防止在3D UI布局中更改组节点的子节点时自动重新计算组节点的中心点位置。Xform节点允许您添加自己的类型的变换和旋转。该文件包含一个平移组件、三个旋转组件和一个缩放组件。当频繁更改旋转值时,例如在场景中更改相机的角度时,拥有三个旋转组件非常有用。

  2. 如果还没有在IDE编辑器中打开MoleculeSampleApp.java文件,请打开该文件,该文件是在创建项目时创建的。将文件顶部的导入语句替换为示例8-1中显示的导入语句。

    示例8-1 替换的导入语句

    import javafx.application.Application;
    import javafx.scene.*;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
  3. MoleculeSampleApp.java中的其余代码替换为示例8-2中显示的代码行。该代码创建了一个新的场景图,其中包含一个Xform作为其节点。

    示例8-2 替换的代码主体

    /**
     * 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. 按下Ctrl+S保存文件。

设置相机

使用Group类和Xform实例来设置相机的层次结构。对相机进行平移和旋转,以改变其默认位置。

  1. 在声明world对象的语句之后,添加以下代码行,如下所示(在示例8-3中显示为粗体)。

    这些代码行创建了一个perspectiveCamera的实例和三个Xform的公共类的实例,Xform类扩展了Group类。 Xform类在您在本文档的前一部分中添加到NetBeans项目中的Xform.java文件中定义。

    示例8-3 添加相机变量

    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. 复制buildCamera()方法的代码行,如示例8-4所示。将它们添加到变量声明的代码行之后。

    buildCamera()方法将相机设置为倒置,而不是默认的JavaFX 2D Y-down。因此,场景被视为一个Y-up(Y轴向上)的场景。

    示例8-4 添加buildCamera()方法

    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. start()方法中,添加对buildCamera()的调用,如示例8-5中所示,以粗体显示。

    示例8-5 添加对buildCamera()方法的调用

    public void start(Stage primaryStage) {
    
            buildCamera();
            
    
  4. 通过复制示例8-6中显示的代码行,并将其添加到start()方法的末尾,将相机设置在场景中。

    示例8-6 在场景中设置相机

    primaryStage.show();
            scene.setCamera(camera);
    
  5. 使用Ctrl+S保存文件。

构建坐标轴

添加用于构建分子的3D坐标轴。使用Box类创建坐标轴,使用PhongMaterial设置镜面和漫反射颜色。在JavaFX中,默认情况下Y轴向下。

按照通常的约定,X轴显示为红色,Y轴显示为绿色,Z轴显示为蓝色。

  1. 示例8-7中显示的以下导入语句添加到源文件的顶部。

    示例8-7 添加两个额外的导入语句

    import javafx.scene.paint.PhongMaterial;
    import javafx.scene.shape.Box;
    
  2. 示例8-8中显示的以下变量声明语句添加到root声明的下一行。

    示例8-8 添加一个用于轴的变量

    private static final double AXIS_LENGTH = 250.0;
    
  3. 示例8-9中显示的以下声明(加粗显示)复制并添加到root声明的下一行。

    示例8-9 创建axisGroup

    final Group root = new Group();
    final Xform axisGroup = new Xform();
    
  4. 示例8-10中显示的buildAxes()方法添加到buildCamera()方法之后。

    示例8-10 添加buildAxes()方法

    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. 示例8-11中显示的对buildAxes()方法的调用(加粗显示)添加到buildCamera()方法之后。

    示例8-11 添加对buildAxes()方法的调用

    buildCamera();
            buildAxes();
    
  6. 通过在项目窗口中右键单击MoleculeSampleApp节点,然后选择运行,编译并运行该项目。一个窗口会出现,显示了3D坐标轴,如图8-1所示。

    图8-1 3D坐标轴

    图8-1的描述
    "图8-1 3D坐标轴"的描述

构建分子

在这一部分中,您将构建分子用户界面。在这里,您将使用Xform类和一些JavaFX 3D图形特性,如PhongMaterial、Sphere和Cylinder。还将使用Xform类。

  1. 要声明moleculeGroup Xform,请复制示例8-12中粗体显示的代码行。将其粘贴在axisGroup变量之后。

    示例8-12 声明moleculeGroup Xform

    final Xform axisGroup = new Xform();
     final Xform moleculeGroup = new Xform();
    
  2. 为buildMolecule()方法中使用的类添加以下导入语句:

    示例8-13 为buildMolecule()方法添加导入语句

    import javafx.scene.shape.Cylinder;
        import javafx.scene.shape.Sphere;
        import javafx.scene.transform.Rotate;
    
  3. 为buildMolecule()方法中使用的HYDROGEN_ANGLE变量添加以下语句,显示为粗体:

    示例8-14 为buildMolecule()方法添加导入语句

    private static final double AXIS_LENGTH = 250.0;
        private static final double HYDROGEN_ANGLE = 104.5;
    
  4. 复制buildMolecule()方法的代码体,并将其粘贴在MoleculeSampleApp.java文件中的buildAxes()方法之后。

  5. start()方法中,添加对buildMolecule()方法的调用,使其显示为示例8-15中的粗体所示。

    示例8-15 添加对buildMolecule()方法的调用

    buildCamera();
    buildAxes();
    buildMolecule();
    
  6. 现在运行项目,您应该看到类似图8-2的内容。

    图8-2 水分子3D模型

    图8-2的描述
    "图8-2 水分子3D模型"的描述

  7. 通过将visible属性修改为false,关闭坐标轴的可见性,如示例8-16所示。再次运行MoleculeSampleApp,您将看到没有坐标轴的运行应用程序。

    示例8-16 将visible属性设置为false

    axisGroup.setVisible(false);
    

添加相机视图控制

handleMouse()handleKeyboard()方法允许您查看不同的相机视图。源代码已经提供,用于演示使用鼠标和键盘按键来操作场景中相机的视图。

  1. 在您即将添加的handleMouse()handleKeyboard()源代码中,添加用于变量声明。复制示例8-17中显示的代码,并粘贴到HYDROGEN_ANGLE声明的行之后。

    示例8-17 添加使用的变量

    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. 复制在handleMouse()handleKeyboard()方法中使用的导入语句,如示例8-18所示。将它们粘贴到MoleculeSampleApp.java文件的顶部。

    示例8-18 添加导入语句

    import javafx.event.EventHandler;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.input.MouseEvent;
    
  3. 3D MoleculeSampleApp Code附录中复制handleMouse()handleKeyboard()方法的代码行。将它们添加到MoleculeSampleApp.java文件的buildMolecule()方法之后。

  4. start()方法中,添加刚刚添加的handleKeyboard()handleMouse()方法的调用。复制示例8-19中显示为粗体的代码行,并将它们粘贴到scene.setFill(Color.GREY)行之后。

    示例8-19 添加方法调用

    Scene scene = new Scene(root, 1024, 768, true);
            scene.setFill(Color.GREY);
            handleKeyboard(scene, world);
            handleMouse(scene, world);
    
  5. 保存文件。

  6. 编译并运行项目。使用以下鼠标或键盘操作来获取不同的视图。

    • 按住鼠标左键并向右或向左拖动鼠标,上下拖动以围绕轴旋转模型的相机视图。

    • 按住鼠标右键并向左拖动鼠标,将相机视图远离模型。向右拖动鼠标,将相机视图靠近分子模型。

    • 按下Ctrl+Z将模型恢复到初始位置。

    • 按下Ctrl+V显示或隐藏分子。

    • 按下Ctrl+X显示或隐藏轴。

关闭窗口

目录

JavaFX: 使用JavaFX图形

展开 折叠