zoukankan      html  css  js  c++  java
  • 【JavaFx教程】第六部分:统计图

    Screenshot AddressApp Part 6

    第6部分的主题

    • 创建一个统计图显示生日的分布。

    生日统计

    在AddressApp中所有人员都有生日。当我们人员庆祝他们生日的时候,如果有一些生日的统计不是会更好。

    我们使用柱状图,包含每个月的一个条形。每个条形显示在指定月份中有多少人需要过生日。

    统计FXML视图

    1. ch.makery.address.view包中我们开始创建一个BirthdayStatistics.fxml(*右击包|New|other..|New FXML Document*) 生日统计FXML

    2. 在Scene Builder中打开BirthdayStatistics.fxml文件。

    3. 选择根节点AnchorPane。在*Layout*组中设置*Pref Width*为620,*Pref Height*为450。

    4. 添加BarChartAnchorPane中。

    5. 右击BarChart并且选择*Fit to Parent*。

    6. 保存fxml文件,进入到Eclipse中,F5刷新项目。

    在我们返回到Scene Builder之前,我们首先创建控制器,并且在我们的MainApp中准备好一切。

    统计控制器

    在view包 ch.makery.address.view中创建一个Java类,称为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;
    
    /**
     * 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);
        }
    }
    

    控制器如何工作

    1. 控制器需要从FXML文件中访问两个元素:

      • barChar:它有StringInteger类型。String用于x轴上的月份,Integer用于指定月份中人员的数量。
      • xAxis:我们使用它添加月字符串
    2. initialize() 方法使用所有月的列表填充x-axis

    3. setPersonData(…)方法将由MainApp访问,设置人员数据。它遍历所有人员,统计出每个月生日的人数。然后它为每个月添加XYChart.Data到数据序列中。每个XYChart.Data对象在图表中表示一个条形。


    连接视图和控制器

    1. 在Scene Builder中打开BirthdayStatistics.fxml

    2. Controller组中设置BirthdayStatisticsController为控制器。

    3. 选择BarChart,并且选择barChar作为fx:id属性(在*Code*组中)

    4. 选择CategoryAxis,并且选择xAxis作为fx:id属性。
      类别轴

    5. 你可以添加一个标题给BarChar(在*Properties*组中)进一步修饰。


    连接View/Controller和MainApp

    我们为*生日统计*使用与*编辑人员对话框*相同的机制,一个简单的弹出对话框。

    添加下面的方法到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();
        }
    }
    

    一切设置完毕,但是我们没有任何东西实际上调用新的showBirthdayStatistics()方法。幸运的是我们已经在RootLayout.fxml中有一个菜单,它可以用于这个目的。

    显示生日统计菜单

    RootLayoutController中添加下面的方法,它将处理*显示生日统计*菜单项的用户点击。

    /**
     * Opens the birthday statistics.
     */
    @FXML
    private void handleShowBirthdayStatistics() {
      mainApp.showBirthdayStatistics();
    }
    

    现在,使用Scene Builder打开RootLayout.fxml文件。创建Staticstic 菜单,带有一个Show Statistcs MenuItem:

    Show Statistics菜单

    选择Show Statistics MenuItem,并且选择handleShowBirthdayStatistics作为On Action(在*Code*组中)。

    Show Statistics On Action

    进入到Eclipse,刷新项目,测试它


    JavaFX Chart的更多信息

    更多信息的一个好地方是官方Oracle教程,使用JavaFX Chart.

    下一步做什么?

    在最后的教程第7部分 中,我们将最后部署我们的应用(例如:打包并且发布应用到我们的用户)

    --------------------- 本文来自 jobbible 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/moshenglv/article/details/82877735?utm_source=copy 

  • 相关阅读:
    前后端分离开发中动态菜单的两种实现方案
    Spring Security 前后端分离登录,非法请求直接返回 JSON
    Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf
    原创的离线版 Redis 教程,给力!
    Spring Boot2 系列教程(八)Spring Boot 中配置 Https
    Anaconda创建环境、删除环境、激活环境、退出环境
    开源一个功能完整的SpringBoot项目框架
    Spring Boot和Spring Cloud学习资源推荐
    Ubuntu 18.04下安装Steam顶级在线游戏平台
    终极手撕之架构大全:分布式+开源框架+微服务+性能优化,够不够?
  • 原文地址:https://www.cnblogs.com/jobbible/p/9718468.html
Copyright © 2011-2022 走看看