
Часть 6: Содержание
- Создание статистической диаграммы для показа распределения дней рождений по месяцам.
Статистика дней рождений
Каждый адресат в нашем приложении AddressApp имеет свой день рождения. Было бы неплохо видеть некоторую статистику о том, когда они празднуют свои дни рождения.
Мы будем использовать столбцовую диаграмму, один столбец будет символизировать один месяц. Каждый столбец будет показывать, сколько дней рождений приходится на его месяц.
FXML-представление статистики
-
Начните с создания внутри пакета
ch.makery.address.viewфайлаBirthdayStatistics.fxml(правый клик на пакете | New | other… | New FXML Document).

-
Откройте файл
BirthdayStatistics.fxmlв приложении Scene Builder. -
Выберите корневой компонент
AnchorPane. Во вкладке Layout установите значение Pref Width в 620, а Pref Height в 450. -
Добавьте на панель
AnchorPaneкомпонентBarChart. -
Кликните правой кнопкой мышки на добавленном
BarChartи выберите Fit to Parent. -
Сохраните fxml-файл, перейдите в Eclipse и обновите проект.
Перед тем, как вернутся в приложение Scene Builder, давайте создадим контроллер и в классе MainApp свяжем всё между собой.
Класс-контроллер статистики
В пакете ch.makery.address.view создайте класс BirthdayStatisticsController.java.
Перед тем, как я начну объяснять что к чему, взгляните на содержимое этого класса:
BirthdayStatisticsController.java
package ch.makery.address.view;
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.XYChart;
import ch.makery.address.model.Person;
/**
* Контроллер для представления статистики дней рождений.
*
* @author Marco Jakob
*/
public class BirthdayStatisticsController {
@FXML
private BarChart<String, Integer> barChart;
@FXML
private CategoryAxis xAxis;
private ObservableList<String> monthNames = FXCollections.observableArrayList();
/**
* Инициализирует класс-контроллер. Этот метод вызывается автоматически
* после того, как fxml-файл был загружен.
*/
@FXML
private void initialize() {
// Получаем массив с английскими именами месяцев.
String[] months = DateFormatSymbols.getInstance(Locale.ENGLISH).getMonths();
// Преобразуем его в список и добавляем в наш ObservableList месяцев.
monthNames.addAll(Arrays.asList(months));
// Назначаем имена месяцев категориями для горизонтальной оси.
xAxis.setCategories(monthNames);
}
/**
* Задаёт адресатов, о которых будет показана статистика.
*
* @param persons
*/
public void setPersonData(List<Person> persons) {
// Считаем адресатов, имеющих дни рождения в указанном месяце.
int[] monthCounter = new int[12];
for (Person p : persons) {
int month = p.getBirthday().getMonthValue() - 1;
monthCounter[month]++;
}
XYChart.Series<String, Integer> series = new XYChart.Series<>();
// Создаём объект XYChart.Data для каждого месяца.
// Добавляем его в серии.
for (int i = 0; i < monthCounter.length; i++) {
series.getData().add(new XYChart.Data<>(monthNames.get(i), monthCounter[i]));
}
barChart.getData().add(series);
}
}
Как работает этот контроллер
-
Контроллеру нужен доступ к двум элементам из нашего fxml-файла:
barChartиспользует типы данныхStringиInteger. Тип данныхStringотображает название месяцев на оси X, а тип данныхInteger- количество записей в конкретном месяце.- Ось
xAxisмы используем для добавления названий месяцев.
-
Метод
initialize()заполняет ось X строковыми значениями названий всех месяцев. -
Метод
setPersonData(...)будет доступен классуMainAppдля передачи данных об адресатах. Он проходится по всем адресатам и подсчитывает количество дней рождений в каждом месяце. Потом он добавляетXYChart.Dataдля каждого месяца в серию данныхXYChart.Series. Каждый объектXYChart.Dataбудет представлять один столбец диаграммы.
Соединяем представление и контроллер
-
В приложении Scene Builder откройте файл
BirthdayStatistics.fxml. -
Во вкладке Controller установите в качестве контроллера
BirthdayStatisticsController. -
Выберите компонент
BarChartи в свойстве fx:id установите значениеbarChart. -
Выберите
CategoryAxisи в свойстве fx:id установите значениеxAxis.
-
Для будущей стилизации, во вкладке Properties вы можете добавить название своей диаграммы.
Соединяем представление/контроллер с классом MainApp
Для отображения статистики дней рождений мы будем использовать тот же механизм, что ранее использовали для отображения окна редактирования данных об адресатах.
Добавьте следующий метод в класс MainApp:
/**
* Открывает диалоговое окно для вывода статистики дней рождений.
*/
public void showBirthdayStatistics() {
try {
// Загружает fxml-файл и создаёт новую сцену для всплывающего окна.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/BirthdayStatistics.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Birthday Statistics");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
// Передаёт адресатов в контроллер.
BirthdayStatisticsController controller = loader.getController();
controller.setPersonData(personData);
dialogStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
Всё готово. Правда, пока метод showBirthdayStatistics() нигде не вызывается. К счастью, в разметке RootLayout.fxml у нас есть меню, которое может быть использовано для этих целей.
Отображаем меню статистики
В класс RootLayoutController добавьте метод, который будет обрабатывать нажатие пункта меню Show Birthday Statistics:
/**
* Открывает статистику дней рождений.
*/
@FXML
private void handleShowBirthdayStatistics() {
mainApp.showBirthdayStatistics();
}
Теперь в приложении Scene Builder откройте файл RootLayout.fxml и создайте меню Statistics с единственным пунктом меню Show Statistics:

Выберите пункт меню Show Statistics и в качестве значения свойства On Action установите метод handleShowBirthdayStatistics.

Перейдите в среду разработки Eclipse, обновите проект и протестируйте ваше приложение.
Больше информации о диаграммах в JavaFX
Хороший источник для получения дополнительной информации о диаграммах в JavaFX - официальный учебник от Oracle Работа с диаграммами в JavaFX
Что дальше?
В последней, 7-й части учебника мы наконец развернём наше приложение (то есть, упакуем и доставим приложение нашим пользователям).