曲线绘制CPU 占有率和统计目录下子目录文件大小

目录

 

前言

项目所用技术与平台

项目功能

项目模块分析

项目细节实现

UI模块

逻辑模块

项目演示 

项目总结


前言

在我学习了JavaSE 和 基本的数据结构以及多线程的知识后,我想着做些什么东西来巩固我所写的知识。于是我就做了实际中我们用电脑可以使用到的功能,实时统计CPU的占有率并绘制曲线,统计磁盘某个文件目录下子目录、子文件所占空间的大小 。

项目所用技术与平台

所用技术:JavaSE/javafx

平台与环境:Windows 10/jdk1.8/idea

项目功能

显示 CPU 占有率

文件目录扫描

项目模块分析

主要分为UI模块和逻辑模块。

UI部分主程序用来加载fxml文件,Controller 主要功能是把UI和逻辑部分关联起来,再就是进行两个Tab页的设计。

逻辑部分主要实现两个功能:1. CPU占用率的获取 2. 磁盘目录的扫描

项目细节实现

UI模块

1. 主函数

package com.bq.gui;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/*
  主程序:继承Application类 重写start()方法
 */
public class FileAndOSMonitorApp extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        //Stage:舞台 Scene:场景
        //1. 加载.fxml文件
        FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().
                getResource("FOMonitor_tab.fxml"));

        //2. 真正的加载
        Parent root = loader.load();

        //加载磁盘空间统计 把统计页面加载到主舞台
        FileAndOSMonitorController controller = loader.getController();
        controller.setPrimaryStage(primaryStage);

        //3. 创建Scene对象 即场景
        Scene scene = new Scene(root, 800, 600);

        //4. 给stage设置标题
        primaryStage.setTitle("FileAndOSMonitor");

        //5. 将scene添加到stage
        primaryStage.setScene(scene);

        //关闭时停止程序
        primaryStage.setOnCloseRequest(event -> controller.shutdown());

        //6. 展示
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

对主函数进行了一些解释,其实主函数更多像一个死套路,继承Application类 重写start()方法,主要目的是进行资源的加载。

2. 磁盘空间扫描Tab页设计

要用自己设计的 UI 替换工程自动生成的 .fxml 文件。 UI 的主题框架是通过 fxml 来描述。UI 交互比较简单,只有两个 tab 页。fxml 中所有元素名称都是 JavaFX 中的类名或者是类的属性名。元素的属性是 JavaFX中类的属性。 这个 UI 主框架包含两个 tab 页,用到的控件是<TabPane> <Tab> <TabPane> 代表 tab 页所在的容器面板, 代表一个个的 tab 页。

CPU 占有率 = CPU 执行程序时间 / 统计周期时间。CPU 占有率 Tab 页主要是通过 <LineChart> 控件绘制曲线图,x 轴 和 y 轴都用 <NumberAxis> 控 件。通过 <Tab> 控件的 onSelectionChanged 属性设置监听事件的方法:handleCPUSelectionChanged。

描述一下,磁盘空间扫描Tab页所用的重要控件:

1. <VBox></VBox>:为垂直布局,布局面板为将多个节点排列在一列中提供了一个简单的方法。

2. <HBox></HBox>:为水平布局,布局面板为将多个节点排列在一行中提供了一个简单的方法。

3. <TabPane> </TabPane>:页签面板,是一种标签页控件。

4. <Tab></Tab>:每个Tab页就可以响应一个页面,可以进行页面间的切换。

5. <LineChart></LineChart>:网格控件,用来显示实时显示cpu占有率。

6. <GridPane></GridPane>:单元格控件,用来显示系统资源的获取情况。

7. <Text></Text>:可编辑的文本页。

8. <Lable></Lable>:标签页。

总体的布局可以由下图表示:

 

3. 文件目录统计Tab页设计

磁盘扫描 Tab 页主要是用到了 <TreeTableView> 控件,绘制一个树形表格。另外设计了一个<Button> 控件来选择文件目录,通 <Button> 控件的 onAction 属性设置监听事件的方法: handleSelectFile。

主要有两个重要的控件:

1. <Button></Button>:按钮组件,会有具体的响应方法。

2.<TreeTableView></TreeTableView>:树表组件,既有树的特性,又有表的特性。用于文件目录的树形结构的查看。

总体的布局可以由下图表示:

4. Controller 模块

Controller 主要是用于处理 UI 事件,需要将此类添加到 .fxml 文件中,我用到的顶级容器是 <VBox> ,通过 fx:controller 属性设置 Controller 类的包路径,方法如下:

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="com.bq.gui.FileAndOSMonitorController">
</VBox>

Controller 中,我们需要处理两个事件:CPU 占有率和目录结构统计,详情见github,大致流程如下:

// 磁盘目录扫描事件处理方法 
public void handleSelectFile(ActionEvent actionEvent) { 
// 1. 打开文件选择对话框 
// 2. 开启磁盘目录扫描线程 
// 3. 渲染TreeTableView 
}

// CPU 占有率事件处理方法 
public void handleCPUSelectionChanged(Event event) { 
// 1. 创建一个定时器,每隔一秒获取一次 CPU 资源绘制曲线图
 // 2. 绘制 LineChart 
}

逻辑模块

1. 系统资源获取模块

系统资源获取采用的是 OperatingSystemMXBean,这是一个 JMX 接口,用于获取运行 JVM 的系统的 资源信息,比如,CPU 占有率,OS 版本,内存大小等等。我们用的是 com.sun.management.OperatingSystemMXBean 类。

绘制 CPU 占有率曲线的核心思想:

      1. 每隔一秒对 CPU 占有率进行一次采样,作为数轴的 y 坐标

      2. 一共保存 60 秒,即 1 分钟的样本点,时间作为 x 坐标。

      3. 用一个数组保存坐标 (x,y),每一次采样,需要把之前采样的坐标点的 x 坐标减 1,这样绘制的时候就会产生移动的效果。

 

核心代码如下:

  //移动数据
    private static final int DATA_LENGTH = 60;
    private static XYPair[] xyPairs = new XYPair[DATA_LENGTH];
    private static int firstIndex = DATA_LENGTH;
    private static void moveCPUData(double cpuPercetage){
        int movIdx = -1; //移动的坐标
        if (firstIndex == 0){
            movIdx = firstIndex + 1;
        }else
            {
                movIdx = firstIndex; firstIndex--;
            }
            for (; movIdx < xyPairs.length; ++movIdx){
                xyPairs[movIdx-1].setX(xyPairs[movIdx].getX()-1);
                xyPairs[movIdx-1].setY(xyPairs[movIdx].getY());
        }
        movIdx--;
        xyPairs[movIdx] = new XYPair(movIdx, cpuPercetage);
    }

2. 文件目录扫描模块

文件目录扫描核心思想是:用递归的方式遍历文件目录结构,统计某个目录下面所有子目录占用总的磁盘空间大小,然后再做一个汇总。

代码片段:

   public static void scannerDirectory(FileTreeNode node) {
        //获取当前目录或文件列表
        File[] files = node.getFile().listFiles();
        if (files == null) {
            return;
        }
        //遍历子目录或者文件
        for (File file : files) {
            FileTreeNode child = new FileTreeNode();
            child.setFile(file);
            child.setFileName(file.getName());

            if (file.isDirectory()) {
                //如果是目录继续统计
                scannerDirectory(child);
            } else {
                //如果是普通文件 记录文件大小
                child.setTotalLength(file.length());
            }
            node.setTotalLength(node.getTotalLength() + child.getTotalLength());
            node.addChildNode(child);
        }
    }

项目演示 

项目总结

这个项目实现了完整的功能,巩固了我对前面知识的学习。在项目中,我也遇到了一些问题:比如gui程序渲染数据必须在主线程中执行,树表控件的转化等等,也都进行了克服。当然还有很多的不足,需要继续完善。

  • 项目优点:引入了 JavaFX 技术,通过图形化 界面展示 CPU 占有率和磁盘空间统计,显得更直观。
  • 项目缺点:项目的所实现的功能相对简单,UI 不够美观。
  • 项目扩展:还可以把项目写的更完善比如: 增加关于内存使用情况的统计,增加关于网络上下行带宽的统计,美化UI,这是我后面要做的工作。

 附:github链接 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值