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

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