Punti nella Parte 6
- Creare un Grafico Statistiche per visualizzare la distribuzione dei compleanni.
Statistiche di Compleanno
Tutte le persone nell’applicazione hanno una data di nascita. Sarebbe carino avere qualche statistica riguardo a quando le persone celebrano il compleanno.
Useremo un Bar Chart contenente una barra per ogni mese. Ogni barra mostra quante persone hanno il loro compleanno in un determinato mese.
La Vista FXML Statistiche
Iniziamo creando il file
BirthdayStatistics.fxml
all’interno del packagech.makery.address.view
(Click destro su package | New | other… | New FXML Document).
Apriamo il file
BirthdayStatistics.fxml
con Scene Builder.Selezioniamo la radice
AnchorPane
. Nel gruppo Layout settare Pref Width a 620 e Pref Height a 450.Aggiungiamo
BarChart
all’AnchorPane
.Click destro su
BarChart
e selezionare Fit to Parent.Salva il file fxml, vai su Eclipse e aggiorna il progetto.
Prima di tornare indietro a Scene Builder creeremo prima il controller e connetteremo tutto nella nostraMainApp
.
Il Controller Statistiche
Nel package vista ch.makery.address.view
creare la classe java chiamata BirthdayStatisticsController.java
.
Diamo prima un’occhiata all’intera classe controller prima di iniziare le spiegazioni:
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); } }
Come funziona il controller
Il controller avrà bisogno dell’accesso a due elementi dal nostro file FXML:
- Il
barChar
: Di tipoString
eInteger
.String
è usato per il mese sull’asse X mentreInteger
è usato per il numero di persone in uno specifico mese. - Il
xAxis
: useremo questo per aggiungere le Strings mese.
- Il
Il metodo
initialize()
riempie l’asse X con una lista di tutti i mesi.Il metodo
setPersonData(...)
verrà utilizzato dalla classeMainApp
per settare i dati personali. Cicla attraverso tutte le persone e conta i compleanni per mese. Quindi aggiungeXYChart.Data
per ogni mese alla serie di dati. Ogni oggettoXYChart.Data
rappresenta una barra nel grafico.
Connettere la Vista al Controller
Apri
BirthdayStatistics.fxml
in Scene Builder.Nel gruppo Controller setta
BirthdayStatisticsController
come controller.Seleziona
BarChart
e sceglibarChart
come fx:id Property (nel gruppo Code).Seleziona
CategoryAxis
e sceglixAxis
come fx:id Property.
Puoi aggiungere un titolo a
BarChart
(nel gruppo Properties) per personalizzare lo stile.
Connettere la Vista/Controller con MainApp
Useremo lo stesso meccanismo per la nostra birthday statistics che abbiamo usato per edit person dialog, un semplice dialog popup.
Aggiungi il seguente metodo alla classe 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(); } }
Ok, abbiamo settato tutto, ma non abbiamo ancora nulla che chiami il nuovo metodo showBirthdayStatistics()
. Fortunatamente abbiamo già un menù in RootLayout.fxml
che può essere usato per questo scopo.
Mostra il Menù Statistiche di Compleanno
Nel tuo RootLayoutController
aggiungi il seguente metodo che si occuperà dei click dell’utente nell’oggetto di menù show birthday statistics:
/** * Opens the birthday statistics. */ @FXML private void handleShowBirthdayStatistics() { mainApp.showBirthdayStatistics(); }
Ora, apri il file RootLayout.fxml
con Scene Builder. Crea il Menu
Statistics con MenuItem
Show Statistics:
Seleziona Show Statistics MenuItem
e scegli handleShowBirthdayStatistics
per On Action
(nel gruppo Code)
Vai a Eclipse, aggiorna il progetto e testalo.
Altre info su JavaFX Charts
Un buon posto per ulteriori informazioni è il tutorial ufficiale della Oracle a Working with JavaFX Charts.
Cosa viene dopo?
Nell’ultimo tutorial Parte 7 finalmente ci occuperemo della distribuzione (i.e. pacchettizzare e distribuire la nostra app agli utenti).