T.M. SoftStudio

feci quod potui, faciant meliora potentes

JavaFX vs Java3D

 

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().