Contenidos en Parte 6
- Creando un Gráfico estadístico para mostrar la distribución de meses de nacimiento.
Estadísticas sobre fecha de nacimiento
Las personas en nuestra libreta de direcciones tienen una fecha de nacimiento. ¿No sería bonito tener algunas estadísticas sobre los meses en que celebran el cumpleaños?.
Usaremos un Gráfico de barras conteniendo una barra para cada mes. Cada barra mostrará cuantas personas en nuestra libreta cumplen años ese mes en particular.
La vista FXML de estadísticas
-
Empezamos creando un archivo
BirthdayStatistics.fxml
dentro del paquetech.makery.address.view
(Clic derecho | New | Other… | New FXML Document).
-
Abre el archivo
BirthdayStatistics.fxml
en Scene Builder. -
Elige el panel raíz
AnchorPane
. En la sección de Layout establece la anchura y altura preferidas (Pref Width, Pref Height) en 620 y 450 respectivamente. -
Añade un componente
BarChart
alAnchorPane
. -
Clic derecho sobre el elemento
BarChart
y elige Fit to Parent. -
Guarda el archivo FXML, vuelve a Eclipse y refresca el proyecto (F5).
Antes de volver a Scene Builder vamos a crear el controlador y a realizar las conexiones necesarias en nuestra MainApp
.
El controlador para las estadísticas
En el paquete de vistas ch.makery.address.view
crea una nueva clase Java denominada BirthdayStatisticsController.java
.
Veamos primero el controlador completo antes de explicarlo:
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; /** * The controller for the birthday statistics view. * * @author Marco Jakob */ public class BirthdayStatisticsController { @FXML private BarChart<String, Integer> barChart; @FXML private CategoryAxis xAxis; private ObservableList<String> monthNames = FXCollections.observableArrayList(); /** * Initializes the controller class. This method is automatically called * after the fxml file has been loaded. */ @FXML private void initialize() { // Get an array with the English month names. String[] months = DateFormatSymbols.getInstance(Locale.ENGLISH).getMonths(); // Convert it to a list and add it to our ObservableList of months. monthNames.addAll(Arrays.asList(months)); // Assign the month names as categories for the horizontal axis. xAxis.setCategories(monthNames); } /** * Sets the persons to show the statistics for. * * @param persons */ public void setPersonData(List<Person> persons) { // Count the number of people having their birthday in a specific month. 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<>(); // Create a XYChart.Data object for each month. Add it to the series. for (int i = 0; i < monthCounter.length; i++) { series.getData().add(new XYChart.Data<>(monthNames.get(i), monthCounter[i])); } barChart.getData().add(series); } }
Como funciona el controlador
-
El controlador necesitará acceso a dos elementos de nuestro archivo FXML:
barChar
: Tiene los tiposString
eInteger
. El tipoString
se utiliza para el mes en el eje-X y el tipoInteger
se utiliza para el número de personas en un mes determinado.xAxis
: Lo usaremos para añadir las nombres de los meses
-
El método
initialize()
rellena el eje-X con la lista de todos los meses. -
El método
setPersonData(...)
será accedido por la claseMainApp
para establecer los datos de personas. Este método recorre todas las personas y cuenta los nacimientos por mes. Entonces añadeXYChart.Data
para cada mes a las series de datos. Cada objetoXYChart.Data
representará una barra en el gráfico.
Conectando vista y controlador
-
Abre
BirthdayStatistics.fxml
en Scene Builder. -
En la sección Controller pon
BirthdayStatisticsController
como controlador. -
Selecciona el componente
BarChart
y ponbarChart
en la propiedad fx:id (sección Code). -
Elige el componente
CategoryAxis
y ponxAxis
como propiedad fx:id.
-
Puedes añadir un título al componente
BarChart
(en Properties) para mejorar la apariencia.
Conectando vista y controlador con MainApp
Para el gráfico de estadísticas usaremos el mismo mecanismo que utilizamos para el diálogo de edición de personas, una ventana de diálogo emergente.
Añade el siguiente método a tu clase MainApp
:
/** * Opens a dialog to show birthday statistics. */ public void showBirthdayStatistics() { try { // Load the fxml file and create a new stage for the popup. 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); // Set the persons into the controller. BirthdayStatisticsController controller = loader.getController(); controller.setPersonData(personData); dialogStage.show(); } catch (IOException e) { e.printStackTrace(); } }
Todo está dispuesto, pero todavía no tenemos nada para invocar al nuevo método showBirthdayStatistics()
. Afortunadamente ya tenemos un menú en en la vista RootLayout.fxml
que puede ser usado para estos fines.
Muestra el menú de estadísticas de cumpleaños
En tu RootLayoutController
añade el siguiente método para gestionar las pulsaciones sobre el ítem de menú Show Statistics:
/** * Opens the birthday statistics. */ @FXML private void handleShowBirthdayStatistics() { mainApp.showBirthdayStatistics(); }
Ahora, abre RootLayout.fxml
en Scene Builder. Crea el menú Statistics con un ítem denominado Show Statistics:
Elige el ítem de menú Show Statistics y establece handleShowBirthdayStatistics
en su campo On Action
(sección Code).
Vuelve a Eclipse, refresca el proyecto y pruébalo.
Más información sobre gráficos JavaFX
Un buen sitio para obtener más información es el tutorial oficial de Oracle: Working with JavaFX Charts.
¿Qué es lo siguiente?
En la última parte del tutorial, Part 7, vamos por fin a desplegar nuestra aplicación (es decir, la empaquetaremos y la haremos llegar a los usuarios).