Часть 1: Содержание
- Знакомство с JavaFX;
- Создание и запуск проекта JavaFX;
- Использование приложения Scene Builder для проектирования пользовательского интерфейса;
- Простая структуризация приложения с использованием шаблона MVC.
Предварительные требования
- Последняя Java JDK 8 (включающая в себя JavaFX 8);
- Среда разработки Eclipse версии 4.4 или выше с установленным плагином e(fx)lipse. Уже настроенную версию Eclipse можно скачать с сайта e(fx)lipse. Или использовать сайт обновлений, если Eclipse уже установлена.
- Приложение Scene Builder версии 8.0 или новее. Сейчас оно предоставляется Gluon, потому как Oracle теперь распространяет его только в виде исходного кода. Предыдущая версия Scene Builder 2.0.
Настройка среды разработки Eclipse
Нам нужно указать среде разработки Eclipse использовать JDK 8, а также задать путь к приложению Scene Builder:
Откройте настройки среды разработки Eclipse и перейдите к пункту Java | Installed JREs.
Нажмите Add…, выберите Standart VM и укажите путь к установленной JDK 8.
Уберите другие добавленные JDK и 8-я JDK будет использоваться по умолчанию.
Перейдите к пункту Java | Compiler. Установите значение настройки Compiler compliance level в 1.8.
Перейдите к пункту JavaFX и укажите путь к исполняемому файлу приложения Scene Builder.
Полезные ссылки
Возможно, вы захотите добавить закладки на следующие ссылки:
- Java 8 API - документация по стандартным классам Java;
- JavaFX 8 API - документация по классам JavaFX;
- ControlsFX API - документация по дополнительным элементам JavaFX из проекта ControlsFX;
- Oracle’s JavaFX Tutorials - официальный учебник по JavaFX от Oracle.
Ну что же, давайте приступим к изучению!
Создание нового проекта JavaFX
В приложение Eclipse (с уже установленным e(fx)clipse) в меню выберите пункт File | New | Other…, и затем выберите JavaFX Project.
Укажите имя проекта (наше будет называться AddressApp) и нажмите Finish.
Если Eclipse автоматически создало какие-то начальные файлы и пакеты, то удалите их.
Создание структуры пакетов
С самого начала мы будем следовать хорошим принципам проектирования ПО. Один из них - это шаблон проектирования Модель-Представление-Контроллер (MVC). Опираясь на этот шаблон мы разобьём код нашего приложения на три части и создадим для каждой из них свой пакет (правый клик на папке src, New… | Package):
ch.makery.address
- содержит большинство классов-контроллеров (Controller) (= классов бизнес логики);ch.makery.address.model
- содержит классы Моделей (Model);ch.makery.address.view
- содержит Представления (View).
Заметка: Внутри пакета view
также будут лежать некоторые классы-контроллеры, которые непосредственно связаны с конкретными представлениями. Давайте называть их контроллеры-представлений (view-controllers).
Создание файла разметки FXML
Есть два пути создания пользовательского интерфейса: либо использовать файл разметки FXML, либо программировать всё на Java. В большинстве своём мы будем использовать XML (.fxml). Я считаю, что этот способ больше подходит для отделения контроллеров от представлений. В дальнейшем мы сможем использовать Scene Builder для визуального редактирования наших XML-файлов. А это значит, что мы не будем напрямую работать с XML.
Кликните на пакете view
правой кнопкой мышки и создайте новый документ FXML с названием PersonOverview
.
Проектировка визуального интерфейса в Scene Builder
Откройте только что созданный fxml-документ в приложении Scene Builder - клик правой кнопкой мышки по файлу PersonOverview.fxml
, Open with SceneBuilder. На вкладке Hierarchy должен находиться единственный компонент AnchorPane.
(Если Scene Builder не запустился, то открываем пункт меню Window | Preferences | JavaFX и настраиваем верный путь к исполняемому файлу установленного приложения Scene Builder).
На вкладке Hierarchy выберите компонент AnchorPane, и справа, на вкладке Layout установите значение характеристикам Pref Width и Pref Height - 600 и 300 соответственно.
На вкладке Hierarchy в компонент AnchorPane добавьте новый компонент SplitPane (horizontal). Кликните по нему правой кнопкой мыши и выберите Fit to Parent.
Теперь, в левую часть компонента SplitPane со вкладки Controls перетащите компонент TableView. Выделите его целиком (а не отдельный столбец) и проставьте отступы от краёв так, как показано на рисунке. Внутри компонента AnchorPane всегда можно проставить отступы от четырёх границ рамки (дополнительная информация о разметках).
Чтобы увидеть, правильно ли отображается созданное окно, выполните пункт меню Preview | Show Preview in Window. Попробуйте поменять размер окна. Добавленная таблица должна изменятся вместе с окном, так как она прикреплена к границам окна.
В таблице измените заголовки колонок (вкладка Properties компонента TableColumn) на “First Name” и “Last Name”.
Выберите компонент TableView и во вкладке Properties измените значение Column Resize Policy на constrained-resize. Выбор этой характеристики гарантирует, что колонки таблицы всегда будут занимать всё доступное пространство.
В правую часть компонента SplitPane перетащите компонент Label и измените его текст на “Person Details” (подсказка: используйте поиск для скорейшего нахождения компонентов). Используя привязки к границам (вкладка Layout) скорректируйте его положение.
На правую панель SplitPane добавьте компонент GridPane и так же настройте привязки к границам, как показано на рисунке.
Приведите своё окно в соответствие с тем, что показано на рисунке, добавляя компоненты Label внутрь ячеек компонента GridPane.
Примечание: для того, чтобы добавить новый ряд в компонент GridPane, выберите существующий номер ряда (он окрасится жёлтым), кликните правой кнопкой мышки на номере ряда и выберите пункт “Add Row Above” или “Add Row Below”.
Внизу добавьте ButtonBar, а в него три кнопки Button. Теперь установите привязки к границам (правой и нижней), чтобы ButtonBar всегда находилась справа.
Так как панель ButtonBar доступна только с JavaFX 8, и её поддержка в Scene Builder на данный момент несколько хромает, то имеется альтернативный способ. Добавьте три компонента Button в правую часть так, как показано на предыдущем рисунке. Выделите их всех вместе (Shift + клик), кликните по ним правой кнопкой мышки и выберите пункт Wrap In | HBox. Это действие их сгруппирует. Вы можете задать расстояние (Spacing) между компонентами во вкладке Properties компонента HBox. Также установите привязки к границам (правой и нижней).
- Если всё сделано правильно, то у нас должно получится что-то похожее на рисунок ниже. Используйте пункт меню Preview, чтобы протестировать созданное окно и его реакцию на изменение размеров.
Создание основного приложения
Нам необходимо создать ещё один файл fxml-разметки, в котором будет компонент полосы меню. Этот файл будет служить обёрткой для только что созданного PersonOverview.fxml
.
В пакете
view
создайте другой fxml-документ, и назовите егоRootLayout.fxml
. На этот раз в качестве корневого элемента выберите BorderPane.
Откройте файл
RootLayout.fxml
в приложении Scene Builder.Установите предпочитаемое значение ширины и высоты компонента: 600 и 400 соответственно.
В верхний слот компонента BorderPane добавьте компонент MenuBar. Функциональность меню мы будем реализовывать в последующих уроках.
Основной класс приложения JavaFX
Теперь нам надо создать основной класс Java, который будет запускать наше приложение с RootLayout.fxml
и добавлять в его центральную область PersonOverview.fxml
.
Кликните правой кнопкой мыши по нашему проекту, перейдите к пункту New | Other… и выберите JavaFX Main Class.
Назовите класс
MainApp
и поместите его в пакетch.makery.address
(примечание: это пакет является родительским дляview
иmodel
).
Созданный класс MainApp.java
расширяет класс Application
и содержит два метода. Это базовая структура, которая необходима для запуска приложения JavaFX. Нам интересен метод start(Stage primaryStage)
. Он автоматически вызывается при вызове метода launch(...)
из метода main
.
Как можно заметить, метод start(...)
в качестве параметра принимает экземпляр класса Stage
. На следующем рисунке представлена структура любого приложения JavaFX:
Источник изображения: http://www.oracle.com/
Это как театральное представление Stage
(театральные подмостки) является основным контейнером, который, как правило, представляет собой обрамлённое окно со стандартными кнопками: закрыть, свернуть, развернуть. Внутрь Stage
добавляется сценаScene
, которая может быть заменена другой Scene
. Внутрь Scene
добавляются стандартные компоненты типа AnchorPane
, TextBox
и другие.
Для получения более детальной информации о такой компоновке обратитесь к этому руководству: Working with the JavaFX Scene Graph.
Откройте класс MainApp.java
и замените его содержимое на это:
package ch.makery.address; import java.io.IOException; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class MainApp extends Application { private Stage primaryStage; private BorderPane rootLayout; @Override public void start(Stage primaryStage) { this.primaryStage = primaryStage; this.primaryStage.setTitle("AddressApp"); initRootLayout(); showPersonOverview(); } /** * Инициализирует корневой макет. */ public void initRootLayout() { try { // Загружаем корневой макет из fxml файла. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml")); rootLayout = (BorderPane) loader.load(); // Отображаем сцену, содержащую корневой макет. Scene scene = new Scene(rootLayout); primaryStage.setScene(scene); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } /** * Показывает в корневом макете сведения об адресатах. */ public void showPersonOverview() { try { // Загружаем сведения об адресатах. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/PersonOverview.fxml")); AnchorPane personOverview = (AnchorPane) loader.load(); // Помещаем сведения об адресатах в центр корневого макета. rootLayout.setCenter(personOverview); } catch (IOException e) { e.printStackTrace(); } } /** * Возвращает главную сцену. * @return */ public Stage getPrimaryStage() { return primaryStage; } public static void main(String[] args) { launch(args); } }
Комментарии могут служить подсказками того, что и как делается.
Запустив приложение мы должны увидеть что-то похожее на то, что изображено на рисунке в начале этой статьи.
Часто встречающиеся проблемы
Если JavaFX не может найти указанный fxml
-файл, то вы получите следующее сообщение об ошибке:
java.lang.IllegalStateException: Location is not set.
Для решения этой проблемы внимательно проверьте правильность указания пути к файлам fxml
и правильность написания его названия.
Что дальше?
Во 2-й части учебника мы добавим в наше приложение некоторые данные и функциональность.