Java3D
Программный интерфейс Java 3D API представляет собой высокоуровневую библиотеку для создания 3D графики, включая анимацию 3D-объектов.
 
Java 3D API оперирует объектами, размещаемыми в графе сцены, который представляет собой дерево 3D-объектов и предназначен для визуализации.
 
Java3D-приложение может работать как настольное приложение, как апплет или как настольное приложение и апплет.
 
Программный интерфейс Java 3D API представлен основным пакетом javax.media.j3d и вспомогательными пакетами com.sun.j3d.utils, java.awt, javax.vecmath
 
По сути, программный интерфейс Java 3D API является оберткой графических систем OpenGL и DirectX.
Инсталляция Java3D
Скачиваем дистрибутив по адресу http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138252.html.
 
Запускаем установочную программу. В результате в каталоге JDK появится папка Java3D.
 
Установленные файлы папки Java3D работают как среда выполнения поверх JDK для программ с использованием программного интерфейса Java 3D API.
 
Для разработки программ с использованием программного интерфейса Java 3D API скачаем плагин NetBeans по адресу http://plugins.netbeans.org/plugin/32144/java-3d и установим его с помощью опции Tools | Plugins | Downloaded | Add Plugins.
 
После этого можно включать импорт библиотек Java 3D API в проект приложения Java.
 
Модель программирования Java3D
Для создания Java3D-приложения в первую очередь создается объект VirtualUniverse.
 
Каждое Java3D-приложение имеет только один объект VirtualUniverse, представляющий виртуальное пространство с которым связан граф сцены.
 
Далее создается объект BranchGroup, представляющий корневой узел ветви графа сцены.
 
Создается объект Transform3D, представляющий пространственные трансформации, и на его основе объект TransformGroup, представляющий узел графа сцены.
 
Создается графический 3D-объект, который добавляется в узел TransformGroup.
 
Узел TransformGroup добавляется в узел BranchGroup, а узел BranchGroup добавляется в виртуальное пространство VirtualUniverse.
 
В узел BranchGroup, помимо графических 3D-объектов, можно также добавлять источники света, освещающие 3D-объекты.
 
Для 3D-объектов можно определять внешний вид с помощью добавления цветов, материалов, текстур и эффектов.
 
С помощью объекта Canvas3D можно создавать 3D-графику программным способом.
 
Анимация 3D-объекта осуществляется с помощью изменения объекта Transform3D во времени.
 
Ниже приведен код простой Java3D-программы, отображающей повернутый куб:
 
package javaapplication3d;
 
 
 
import com.sun.j3d.utils.geometry.ColorCube;
 
import com.sun.j3d.utils.universe.SimpleUniverse;
 
import javax.media.j3d.BranchGroup;
 
import javax.media.j3d.Transform3D;
 
import javax.media.j3d.TransformGroup;
 
 
 
public class JavaApplication3D {
 
 
 
   public JavaApplication3D()
 
 
 
{
 
 
 
   SimpleUniverse universe = new SimpleUniverse();
 
 
 
   BranchGroup group = new BranchGroup();
 
   ColorCube cube=new ColorCube(0.3);
 
   Transform3D rotate = new Transform3D();
 
   rotate.rotX(10);  
 
   TransformGroup rotateGroup = new TransformGroup();
 
   rotateGroup.setTransform(rotate);
 
   rotateGroup.addChild(cube);  
 
   group.addChild(rotateGroup);
 
   universe.getViewingPlatform().setNominalViewingTransform();
 
 
 
   universe.addBranchGraph(group);
 
 
 
}
 
    public static void main(String[] args) {
 
        JavaApplication3D javaApplication3D = new JavaApplication3D();
 
    }
 
}
 
JavaFX
Платформа JavaFX обеспечивает создание мощного графического интерфейса пользователя (Graphical User Interface (GUI)) для крупномасштабных приложений, ориентированных на обработку данных, насыщенных медиа-приложений, поставляющих разнообразный медиа-контент пользователю, Mashup-приложений, объединяющих различные Web-ресурсы для пользователя, компонентов высококачественной графики и анимации для Web-сайтов, различного рода пользовательских программ, насыщенных графикой, анимацией и интерактивными элементами.
 
Один и тот же Java-код, созданный на базе платформы JavaFX, может запускаться как настольное приложение, которое разворачивается на клиентском компьютере автономно, может разворачиваться как Java Web Start приложение, или может отображаться в Web-браузере как JavaFX-апплет, встроенный в HTML-страничку.
 
Платформа JavaFX предоставляет современные GUI-компоненты, богатый набор графических и медиа библиотек, а также высокопроизводительную среду выполнения приложений.
 
Для альтернативного декларативного описания графического интерфейса пользователя платформа JavaFX предлагает язык FXML. Кроме того, платформа JavaFX обеспечивает графический и медиа движки, улучшающие воспроизведение графического и мультимедийного контента, встраивание HTML-контента в приложение, плагин для Web-браузеров, широкий выбор GUI-компонентов с поддержкой CSS3. При этом платформа JavaFX содержит:
 
Набор JavaFX SDK, предоставляющий инструмент JavaFX Packager tool компиляции, упаковки и развертывания JavaFX-приложений, Ant-библиотеку для сборки JavaFX-приложений, библиотеки JavaFX API и документацию.
Среду выполнения JavaFX Runtime для работы настольных JavaFX-приложений и JavaFX-апплетов.
Поддержку платформы JavaFX для среды выполнения NetBeans IDE 7.
 Примеры JavaFX-приложений.
Платформа JavaFX интегрирована в платформу JDK 7, и не требует отдельной инсталляции.
 
Сайт платформы JavaFX находится по адресу http://javafx.com/.
 
Плагин JavaFX Web-браузера не является надстройкой Web-браузера, а его работа определяется JavaScript-кодом, который встраивает JavaFX-код в качестве JavaFX-апплета в Web-страничку, подключая установленную на локальном компьютере среду выполнения JavaFX Runtime.
 
Инсталляция JavaFX
Для установки платформы JavaFX достаточно скачать и установить JDK 7 (http://www.oracle.com/technetwork/java/javase/downloads/index.html).
 
Для разработки приложений на базе платформы JavaFX достаточно скачать и установить NetBeans IDE 7 (http://netbeans.org/downloads/).
 
При выборе в меню File среды NetBeans опции New Project | JavaFX появятся шаблоны проектов JavaFX Application, JavaFX Preloader и JavaFX FXML Application.
 
Модель программирования JavaFX
Один и тот же код JavaFX-приложения может запускаться в качестве настольного приложения, которое разворачивается на клиентском компьютере автономно, может разворачиваться как Java Web Start приложение, или может отображаться в Web-браузере как JavaFX-апплет, встроенный в HTML-страничку.
 
Точкой входа в JavaFX-приложение служит Java-класс, расширяющий абстрактный класс javafx.application.Application и содержащий метод main():
 
public class JavaFXApp extends Application {
 
 
 
    public static void main(String[] args) {
 
        launch(args);
 
    }
 
    public void init(){
 
   
 
. . .
 
}
 
    @Override
 
    public void start(Stage primaryStage) {
 
       
 
. . .
 
        primaryStage.setScene(scene);
 
        primaryStage.setVisible(true);
 
}
 
 
 
public void stop(){
 
. . .
 
}   
 
}
 
В методе main() главного класса JavaFX-приложения вызывается метод launch() класса Application, отвечающий за загрузку JavaFX-приложения. Кроме того, главный класс JavaFX-приложения должен переопределить абстрактный метод start() класса Application, обеспечивающий создание и отображение сцены JavaFX-приложения.
 
Методы init() и stop() класса Application могут использоваться для инициализации данных и освобождения ресурсов JavaFX-приложения.
 
Так как метод init() вызывается перед созданием главного потока приложения JavaFX Application Thread, то инициализация JavaFX-приложения в методе init() с участием узлов графа сцены должна осуществляться с применением статического метода javafx.application.Platform.runLater().
 
Для выполнения JavaScript-кода на Web-странице, содержащей JavaFX-приложение, главный класс JavaFX-приложения может использовать метод getHostServices() класса Application и объект netscape.javascript.JSObject.
 
Обработка входных аргументов или параметров в главном классе JavaFX-приложения может быть осуществлена с помощью вызова метода getParameters() класса Application.
 
Улучшить отображение и обработку процесса запуска и загрузки JavaFX-приложения можно несколькими способами. Первый способ – это использование обработчика onGetSplash JavaScript-библиотеки Deployment Toolkit API для создания заставки запуска JavaFX-апплета, встроенного в Web-страничку. Другой способ – это применение CSS-стилей к Preloader-предзагрузчику по умолчанию. И наконец, можно создать свой класс предзагрузчика, расширяющий абстрактный класс javafx.application.Preloader и сослаться на него в JNLP-дескрипторе развертывания JavaFX-приложения. При этом для связи главного класса JavaFX-приложения с предзагрузчиком можно использовать метод notifyPreloader() класса Application.
 
Метод start() класса Application содержит в качестве параметра объект javafx.stage.Stage, представляющий графический контейнер главного окна JavaFX-приложения. Данный объект Stage создается средой выполнения при запуске JavaFX-приложения и передается в метод start() главного класса JavaFX-приложения, что позволяет использовать методы объекта Stage для установки и отображения сцены JavaFX-приложения. Вместо объекта Stage, аргумента метода start(), разработчик может создать свой экземпляр класса Stage для отображения сцены JavaFX-приложения.
 
Перед установкой и отображением сцены в графическом контейнере Stage главного окна JavaFX-приложения необходимо создать граф сцены, состоящий из корневого узла и его дочерних элементов, и на его основе создать объект javafx.scene.Scene сцены.
 
Как правило, в качестве корневого узла используется объект javafx.scene.Group, который создается с помощью конструктора и используется в качестве аргумента конструктора при создании объекта javafx.scene.Scene.
 
Дочерние узлы графа сцены, представляющие графику, элементы контроля GUI-интерфейса, медиаконтент, добавляются в корневой узел с помощью метода getChildren().add() или метода getChildren().addAll(). При этом дочерние узлы могут иметь визуальные эффекты, режимы наложения, CSS-стили, прозрачность, трансформации, обработчики событий, участвовать в анимации по ключевым кадрам, программируемой анимации и др.
 
Ниже приведен код приложения JavaFX, отображающего повернутый куб:
 
package javafxapp;
 
 
 
import javafx.application.Application;
 
import javafx.scene.Group;
 
import javafx.scene.Scene;
 
import javafx.scene.paint.Color;
 
import javafx.scene.text.Font;
 
import javafx.stage.Stage;
 
 
 
public class JavaFXApp extends Application {
 
   
 
    @Override
 
    public void start(Stage primaryStage) {
 
       Cube c = new Cube(50,Color.BLUE,2);
 
       c.setLayoutX(50);
 
       c.setLayoutY(50);
 
Group root = new Group();
 
root.getChildren().addAll(cmHome,cmServices, cmBlog, cmContacts, content1,content2);       
 
        Scene scene = new Scene(root, 800, 600);
 
        scene.setFill(Color.BLACK);      
 
        primaryStage.setScene(scene);
 
        primaryStage.show();
 
    }
 
 
 
    public static void main(String[] args) {
 
        launch(args);
 
    }
 
}
 
package javafxapp;
 
 
 
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.control.Hyperlink;
 
import javafx.scene.control.HyperlinkBuilder;
 
import javafx.scene.input.MouseEvent;
 
import javafx.scene.layout.StackPane;
 
import javafx.scene.paint.Color;
 
import javafx.scene.shape.Rectangle;
 
import javafx.scene.shape.RectangleBuilder;
 
import javafx.scene.text.Font;
 
import javafx.scene.transform.Rotate;
 
import javafx.util.Duration;
 
 
 
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 MenuContainer(double size, Color colorContainer, double shade) {
 
            rx.setAngle(15);
 
            ry.setAngle(15);
 
            rz.setAngle(0);
 
            this.getTransforms().addAll(rz, ry, rx);
 
          final Group group=this;
 
            //
 
final Rectangle   backFace =   RectangleBuilder.create() // back face
 
.width(size*2).height(size)
 
.fill(colorContainer.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
 
.translateX(-0.5*size)
 
.translateY(-0.5*size)
 
.translateZ(0.5*size)                   
 
.build()
 
;
 
           
 
              //
 
final Rectangle   bottomFace =  RectangleBuilder.create() // bottom face
 
.width(size*2).height(size)
 
.fill(colorContainer.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
 
.translateX(-0.5*size)
 
.translateY(0)
 
.rotationAxis(Rotate.X_AXIS)
 
.rotate(90)                 
 
.build();
 
 //
 
 //
 
final Rectangle   rightFace =   RectangleBuilder.create() // right face
 
.width(size).height(size)
 
.fill(colorContainer.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
 
.translateX(1*size)
 
.translateY(-0.5*size)
 
.rotationAxis(Rotate.Y_AXIS)
 
.rotate(90)                  
 
.build();
 
 //
 
 //
 
final Rectangle   leftFace =   RectangleBuilder.create() // left face
 
.width(size).height(size)
 
.fill(colorContainer.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
 
.translateX(-1*size)
 
.translateY(-0.5*size)
 
.rotationAxis(Rotate.Y_AXIS)
 
.rotate(90)                  
 
.build();
 
 //
 
 //
 
final Rectangle   topFace =  RectangleBuilder.create() // top face
 
.width(size*2).height(size)
 
.fill(colorContainer.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0))
 
.translateX(-0.5*size)
 
.translateY(-1*size)
 
.rotationAxis(Rotate.X_AXIS)
 
.rotate(90)                   
 
.build();
 
 //
 
 //
 
           
 
final Rectangle   face = RectangleBuilder.create() // face
 
.width(size*2).height(size)
 
.fill(colorContainer)                 
 
.build();
 
face.setTranslateX(-0.5*size);
 
face.setTranslateY(-0.5*size);
 
face.setTranslateZ(-0.5*size);
 
            
 
final   Timeline animation = new Timeline();
 
animation.getKeyFrames().addAll(
 
new KeyFrame(Duration.ZERO, new KeyValue(rx.angleProperty(), 15d)),                      
 
new KeyFrame(new Duration(1000), new KeyValue(rx.angleProperty(), 375d))                       
 
);
 
animation.setCycleCount(Animation.INDEFINITE);
 
group.setOnMouseDragged(new EventHandler<MouseEvent>() {
 
@Override
 
public void handle(MouseEvent event) {         
 
animation.play();   
 
double x= event.getSceneX();
 
double y = event.getSceneY();         
 
group.setLayoutX(x);
 
group.setLayoutY(y);
 
group.setOnMouseReleased(new EventHandler<MouseEvent>() {
 
@Override
 
public void handle(MouseEvent event) {
 
animation.stop();
 
rx.angleProperty().set(15);
 
}
 
});
 
} });
 
//
 
getChildren() .addAll(backFace,bottomFace,rightFace,leftFace,topFace,face);
 
}
 
}
 
Сравнение JavaFX и Java3D
JavaFX и Java3D включают в себя программный интерфейс и среду выполнения.
Java3D требует отдельной инсталляции, а JavaFX включена в JDK 7.
JavaFX и Java3D позволяют создавать 3D-графику.
Java3D предоставляет готовые 3D-объекты, а JavaFX позволяет создавать 3D-объекты из 2D-примитивов.
JavaFX предоставляет GUI-компоненты, а Java3D нет.
JavaFX и Java3D обеспечивают трансформации и анимации объектов.
Код JavaFX автоматически компилируется в настольное приложение и в апплет. Для создания Java3D-апплета требуется дополнительный код.
JavaFX и Java3D оперируют графом сцены.
 JavaFX обеспечивает декларативное описание графа сцены и визуальный редактор графа сцены, а Java3D нет.
Java3D обеспечивает поддержку текстур, а JavaFX нет.
Код JavaFX должен выполняться в отдельном потоке JavaFX Application Thread, код Java3D выполняется в основном потоке.
Точкой входа в JavaFX-приложение служит Java-класс, расширяющий абстрактный класс javafx.application.Application и содержащий метод main(), точкой входа в Java3D-приложение служит обычный Java-класс с методом main().