JavaFX Tutorial (Italiano)

Parte 6: Grafico delle Statistiche

Screenshot AddressApp Part 6

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

  1. Iniziamo creando il file BirthdayStatistics.fxml all’interno del package ch.makery.address.view (Click destro su package | New | other… | New FXML Document).
    Birthday Statistics FXML

  2. Apriamo il file BirthdayStatistics.fxml con Scene Builder.

  3. Selezioniamo la radice AnchorPane. Nel gruppo Layout settare Pref Width a 620 e Pref Height a 450.

  4. Aggiungiamo BarChart all'AnchorPane.

  5. Click destro su BarChart e selezionare Fit to Parent.

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

  1. Il controller avrà bisogno dell’accesso a due elementi dal nostro file FXML:

    • Il barChar: Di tipo String e Integer. String è usato per il mese sull’asse X mentre Integer è usato per il numero di persone in uno specifico mese.
    • Il xAxis: useremo questo per aggiungere le Strings mese.
  2. Il metodo initialize() riempie l’asse X con una lista di tutti i mesi.

  3. Il metodo setPersonData(...) verrà utilizzato dalla classe MainApp per settare i dati personali. Cicla attraverso tutte le persone e conta i compleanni per mese. Quindi aggiunge XYChart.Data per ogni mese alla serie di dati. Ogni oggetto XYChart.Data rappresenta una barra nel grafico.


Connettere la Vista al Controller

  1. Apri BirthdayStatistics.fxml in Scene Builder.

  2. Nel gruppo Controller setta BirthdayStatisticsController come controller.

  3. Seleziona BarChart e scegli barChart come fx:id Property (nel gruppo Code).

  4. Seleziona CategoryAxis e scegli xAxis come fx:id Property.
    Category Axis

  5. 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:

Show Statistics Menu

Seleziona Show Statistics MenuItem e scegli handleShowBirthdayStatistics per On Action (nel gruppo Code)

Show Statistics On Action

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

Qualche altro articolo che potresti trovare interessante