曲線繪製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鏈接 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章