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