Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
JavaFX.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
4.88 Mб
Скачать

3.5.1 JavaFx Scene Builder

Створіть новий проект JavaFX FXML application з назвою JavaFX3DCube. Запустивши JavaFX Scene Builder потрібно відкрити FXML файл, який знаходиться в директорії тільки-но створеного проекту (рис. 3.35).

Потрібно видалити елемент Lable, додати на сцену VBox та перемістити туди кнопку. Також у VBox потрібно помістити HBox. В вкладці Properties елементу HBox потрібно встановити значення CENTER властивості Alignment.

Розтягнувши VBox та його внутрінші елементи на ширину вікна, можна додати файл стилів. Спершу для цього потрібно скопіювати будь-який існуючий файл стилів у проект, а потім в JavaFX Scene Builder обрати кореневий елемент AnchorPane і на панелі властивостей натиснувши «+» в розділі Stylesheets, вибрати скопійований стиль. В розділі Style Class, також натиснувши на «+», потрібно зі списку класів обрати root. В результаті елемент змінить свій стиль відповідно до обраного класу. За допомогою пункту меню Show Preview Window в розділі Preview можна подивитись на результат (рис. 3.36).

Рис. 3.35. JavaFX Scene Builder з відкритим FXML файлом проекту

Останнє, що потрібно зробити — змінити контролер, який буде обробляти цей файл. Для цього на вкладці Document потрібно змінити властивість Controller class на javafx3dcube.ViewController (клас вказаний з пакетом).

Рис. 3.36. Вигляд розробленого інтерфейсу зі стилями

Після збереження змін потрібно перейти до NetBeans та змінити ім’я FXML файлу на View.fxml та ім’я класу Sаmple на ViewController.

3.5.2 Створення логіки додатка

Додаток міститиме в собі 3-D куб, який буде обертатися. За допомогою кнопки він буде зупинятися або продовжувати обертання. Цей куб буде утворюватися із групи шістьох прямокутників. Вони будуть об’єднані у клас, який успадковується від класу Group. Це дозволить звертатися до них та керувати ними як одним цільним об’єктом, що є дуже комфортно. Отже створіть клас Cube з наступним кодом:

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 Cube(double size, Color color, double shade) {

getTransforms().addAll(rz, ry, rx);

getChildren().addAll(

RectangleBuilder.create() // back face

.width(size).height(size)

.fill(color.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0))

.translateX(-0.5*size)

.translateY(-0.5*size)

.translateZ(0.5*size)

.build(),

RectangleBuilder.create() // bottom face

.width(size).height(size)

.fill(color.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0))

.translateX(-0.5*size)

.translateY(0)

.rotationAxis(Rotate.X_AXIS)

.rotate(90)

.build(),

RectangleBuilder.create() // right face

.width(size).height(size)

.fill(color.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(),

RectangleBuilder.create() // left face

.width(size).height(size)

.fill(color.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0))

.translateX(0)

.translateY(-0.5*size)

.rotationAxis(Rotate.Y_AXIS)

.rotate(90)

.build(),

RectangleBuilder.create() // top face

.width(size).height(size)

.fill(color.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0))

.translateX(-0.5*size)

.translateY(-1*size)

.rotationAxis(Rotate.X_AXIS)

.rotate(90)

.build(),

RectangleBuilder.create() // front face

.width(size).height(size)

.fill(color)

.translateX(-0.5*size)

.translateY(-0.5*size)

.translateZ(-0.5*size)

.build()

);

}

}

Для кожної сторони куба (прямокутника) використовується RectangleBuilder, який створює об’єкт прямокутника із заданими параметрами. Встановлюється ширина, висота, колір, потім задається позиція (зсувами по вісям координат) і, якщо потрібно, обертається відносно необхідної осі. Властивості rx, ry, rz відповідають градусам нахилу кубу за вісями. Саме за їх допомогою буде створена анімація обертання кубу.

В головному класі JavaFX3DCube потрібно створити метод, який буде повертати налаштований куб, а саме — встановлювати його положення та додавати до нього анімацію.

public static Timeline animation;

public Node create3dContent() {

animation = new Timeline();

Cube c = new Cube(50,Color.LIGHTGRAY,1);

c.rx.setAngle(45);

c.ry.setAngle(45);

animation.getKeyFrames().addAll(

new KeyFrame(Duration.ZERO,

new KeyValue(c.rz.angleProperty(), 0d)),

new KeyFrame(Duration.seconds(1),

new KeyValue(c.rz.angleProperty(), 360d)

));

animation.setCycleCount(Animation.INDEFINITE);

return c;

}

Отже куб є нахиленим на 45 градусів відносно вказаних осей, а анімація буде повертати його за допомогою властивості rz на 360 градусів зі швидкістю один оберт за секунду.

Також потрібно додати метод, який буде викликатися по закінченню роботи додатку — він буде зупиняти анімацію:

@Override public void stop() {

animation.stop();

}

Останнє, що потрібно змінити в цьому класі — це метод запуску додатку:

private HBox cPlace;

@Override

public void start(Stage stage) throws Exception {

Parent root = FXMLLoader.load(getClass().getResource("View.fxml"));

Scene scene = new Scene(root);

cPlace = (HBox)root.lookup("#hBox1");

cPlace.getChildren().add(create3dContent());

root.setDepthTest(DepthTest.ENABLE);

scene.setCamera(new PerspectiveCamera());

stage.setScene(scene);

stage.show();

}

В ньому відбувається завантаження FXML файлу та створення сцени. Для додавання кубу до сцени використовується метод lookup, який повертає Node об’єкт елементу (або перше входження) з FXML файлу за сss селектором, в даному випадку елемент знаходиться за допомогою id. Для використання 3-D необхідно активізувати Z-буферизацію за допомогою DepthTest та використовувати перспективну камеру.

Тепер потрібно додати обробник натискання кнопки у контролері, яка буде запускати або зупиняти анімацію. Через те, що ініціалізація не використовуються, весь клас можна трохи спростити:

public class ViewController{

private boolean stop=false;

@FXML private void handleButtonAction(ActionEvent event) {

if (stop){

JavaFX3DCube.animation.pause();

stop=false;

} else {

JavaFX3DCube.animation.play();

stop=true;

}

}

}

Запустивши додаток можна подивитись на результат (рис. 3.37).