栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java简易系统监视器system-monitoring

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java简易系统监视器system-monitoring

Java简易系统监视器system-monitoring:实时显示CPU使用率、内存使用率、笔记本电脑电池剩余电量、时间(时、分、秒)。创建系统托盘,设置系统托盘菜单,窗体置顶显示。通过jna调用dll文件读取电池数据。

目录

效果图

功能说明

项目与工具

项目说明

目录结构

核心代码

Window.java

Dll.java

AppUtil.java

BatteryLabel.java

C++创建dll

BatteryMonitor.h

BatteryMonitor.cpp

依赖

Github

Gitee

参考链接

后记


效果图

功能说明
    Java简易系统监视器system-monitoring:实时显示CPU使用率、内存使用率、笔记本电脑电池剩余电量、时间(时、分、秒)。CPU使用率、内存使用率和时间每秒更新一次,笔记本电脑电池剩余电量每15秒更新一次。创建系统托盘,设置系统托盘菜单,窗体置顶显示。系统托盘按钮:
      移动(或固定):点击后可移动或固定窗体。刷新:点击可刷新窗体,当窗体显示异常时可使用。布局:可更改窗体布局,可选“单列布局”、“双列布局”。(效果图为双列布局)显示:可选择需要显示的参数,可勾选“CPU”、“内存”、“电量”、“时间”。退出程序:点击可退出程序。
    窗体不可移动至屏幕外。窗体大小可根据显示的参数个数自动适配。点击系统托盘后,弹出多级菜单,当鼠标点击非菜单区域,弹出的多级菜单会自动消失。(基于Jframe+JPopupMenu实现)

项目与工具

Maven、Java 8、Swing、maven-assembly-plugin(jar-with-dependencies)、jna、dll

项目说明
    使用jna调用C++生成的动态链接库dll文件监控电池剩余电量。生成的system-monitoring-2.0.0-jar-with-dependencies.jar需与resources中的images文件夹和BatteryMonitor.dll文件同级。(与代码中读取相关文件路径的写法有关)

目录结构

核心代码

由于代码较多,此处就不全部贴出来了,需要完整代码的小伙伴请移步GitHub或Gitee。

Window.java
package cxzgwing;

import java.awt.*;
import java.time.Clock;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

import cxzgwing.judgement.WindowMovable;
import cxzgwing.label.impl.BatteryLabel;
import cxzgwing.label.impl.CpuLabel;
import cxzgwing.label.impl.MemoryLabel;
import cxzgwing.label.impl.TimeLabel;
import cxzgwing.listener.frameDragListener;
import cxzgwing.listener.TrayIconMouseListener;
import cxzgwing.task.BatteryMonitorTask;
import cxzgwing.task.CpuMemoryTimeMonitorTask;
import cxzgwing.task.GCTask;
import cxzgwing.utils.AppUtil;
import cxzgwing.utils.LabelLayout;
import cxzgwing.utils.ThreadUtil;

public class Window extends Jframe {
    private Menu menu;
    private WindowMovable windowMovable;
    private CpuLabel cpuLabel;
    private MemoryLabel memoryLabel;
    private BatteryLabel batteryLabel;
    private TimeLabel timeLabel;
    private Font font;
    private EmptyBorder emptyBorder;
    private GridLayout gridLayout;
    // 1-单列布局,2-双列布局
    private int labelLayout;

    // 窗体位置最大横坐标
    private int windowMaxX;
    // 窗体位置最大纵坐标
    private int windowMaxY;

    public Window() throws Exception {
        // 初始化窗体是否可移动
        windowMovable = new WindowMovable(false);
        font = new Font("黑体", Font.PLAIN, 16);
        labelLayout = LabelLayout.DOUBLE;

        // 设置显示标签边距
        emptyBorder = new EmptyBorder(0, 5, 0, 0);
        // 设置布局
        gridLayout = new GridLayout(2, 2);

        // 初始化窗体
        initWindow();

        // 设置CPU使用率显示标签
        initCpuJLabel();

        // 内存使用率显示标签
        initMemJLabel();

        // 电池电量百分比显示标签
        initBatteryJLabel();

        // 时间显示标签
        initTimeJLabel();

        // 初始化托盘菜单
        initMenu();

        // 设置窗体是否可移动监听
        setWindowDragListener();

        // 添加窗体状态监听,使窗体一直显示
        setWindowAlwaysShow();

        // 添加系统托盘
        setSystemTray();

        // 显示
        this.setVisible(true);

        // 监控
        monitoring();
    }

    private void initMenu() {
        menu = new Menu(this, windowMovable, cpuLabel, memoryLabel, batteryLabel, timeLabel);
    }

    
    private void initWindow() {
        // 隐藏任务栏图标
        this.setType(Jframe.Type.UTILITY);
        // 设置窗口置顶
        this.setAlwaysonTop(true);
        // 设置无边框
        this.setUndecorated(true);
        // 设置背景色
        this.setBackground(new Color(0, 0, 0, 80));
        // 设置窗体大小
        this.setSize(150, 40);
        // 设置布局
        this.setLayout(gridLayout);

        AppUtil.initWindowLocation(this);
    }

    private void setWindowDragListener() {
        // 设置鼠标监听,可通过鼠标移动窗体位置
        // 通过系统托盘菜单中的第一个按钮(移动 / 固定)来控制是否能移动窗体
        frameDragListener frameDragListener = new frameDragListener(this, windowMovable);
        this.addMouseListener(frameDragListener);
        this.addMouseMotionListener(frameDragListener);
    }

    private void initTimeJLabel() {
        // 时间显示标签
        timeLabel = new TimeLabel(AppUtil.getTime());
        timeLabel.setFont(font);
        timeLabel.setForeground(Color.WHITE);
        timeLabel.setBorder(emptyBorder);
        gridLayout.addLayoutComponent("timeLabel", timeLabel);
        this.add(timeLabel);
    }

    private void initBatteryJLabel() {
        // 电池电量百分比显示标签
        batteryLabel = new BatteryLabel(AppUtil.getBatteryPercent());
        batteryLabel.setFont(font);
        batteryLabel.setForeground(Color.WHITE);
        batteryLabel.setBorder(emptyBorder);
        gridLayout.addLayoutComponent("batteryLabel", batteryLabel);
        this.add(batteryLabel);
    }

    private void initMemJLabel() {
        // 内存使用率显示标签
        memoryLabel = new MemoryLabel(AppUtil.getMemoryLoad());
        memoryLabel.setFont(font);
        memoryLabel.setForeground(Color.WHITE);
        memoryLabel.setBorder(emptyBorder);
        gridLayout.addLayoutComponent("memoryLabel", memoryLabel);
        this.add(memoryLabel);
    }

    private void initCpuJLabel() {
        // CPU使用率显示标签
        cpuLabel = new CpuLabel(AppUtil.getSystemCpuLoad());
        cpuLabel.setFont(font);
        cpuLabel.setForeground(Color.WHITE);
        cpuLabel.setBorder(emptyBorder);
        gridLayout.addLayoutComponent("cpuLabel", cpuLabel);
        this.add(cpuLabel);
    }

    
    private void monitoring() {
        ThreadUtil.addTask(new CpuMemoryTimeMonitorTask(cpuLabel, memoryLabel, timeLabel));
        ThreadUtil.addTask(new BatteryMonitorTask(batteryLabel));
        ThreadUtil.addTask(new GCTask());
    }

    
    private void setSystemTray() throws Exception {
        try {
            if (SystemTray.isSupported()) {
                // 获取当前平台的系统托盘
                SystemTray tray = SystemTray.getSystemTray();

                // 加载一个图片用于托盘图标的显示
                Image image = Toolkit.getDefaultToolkit()
                        .getImage(Clock.class.getResource("/images/system-monitoring-icon.png"));

                // 创建点击图标时的弹出菜单方案三:Jframe + JPopupMenu
                TrayIcon trayIcon = new TrayIcon(image, "System Monitoring");
                trayIcon.addMouseListener(new TrayIconMouseListener(menu));

                // 托盘图标自适应尺寸
                trayIcon.setImageAutoSize(true);

                // 添加托盘图标到系统托盘
                tray.add(trayIcon);

            } else {
                throw new Exception("当前系统不支持系统托盘");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    
    private void setWindowAlwaysShow() {
        this.addWindowStateListener(e -> {
            int newState = e.getNewState();
            if (Jframe.IConIFIED == newState) {
                this.setState(Jframe.NORMAL);
            }
        });
    }

    public void setWindowMaxX(int windowMaxX) {
        this.windowMaxX = windowMaxX;
    }

    public void setWindowMaxY(int windowMaxY) {
        this.windowMaxY = windowMaxY;
    }

    public int getWindowMaxX() {
        return this.windowMaxX;
    }

    public int getWindowMaxY() {
        return this.windowMaxY;
    }

    public int getLabelLayout() {
        return labelLayout;
    }

    public void setLabelLayout(int labelLayout) {
        this.labelLayout = labelLayout;
    }

}

Dll.java
package cxzgwing.dll;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface Dll extends Library {
    Dll dll = Native.load("BatteryMonitor", Dll.class);

    int BatteryPercent();
}

AppUtil.java
package cxzgwing.utils;

import java.awt.*;
import java.lang.management.ManagementFactory;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import com.sun.management.OperatingSystemMXBean;

import cxzgwing.Window;
import cxzgwing.dll.Dll;

public class AppUtil {
    private static OperatingSystemMXBean systemMXBean;
    static {
        systemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    }

    public static String getTime() {
        return LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
    }

    public static String getMemoryLoad() {
        double totalPhysicalMemorySize = systemMXBean.getTotalPhysicalMemorySize();
        double freePhysicalMemorySize = systemMXBean.getFreePhysicalMemorySize();
        double value = freePhysicalMemorySize / totalPhysicalMemorySize;
        return "M: " + String.format("%.1f", (1 - value) * 100) + "%";
    }

    public static String getSystemCpuLoad() {
        return "C: " + String.format("%.1f", systemMXBean.getSystemCpuLoad() * 100) + "%";
    }

    public static String getBatteryPercent() {
        int value = 225;
        try {
            value = Dll.dll.BatteryPercent();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "B: " + value + "%";
    }

    public static void initWindowLocation(Window window) {
        // 获得窗体宽
        int windowWidth = window.getWidth();
        // 获得窗体高
        int windowHeight = window.getHeight();
        // 定义工具包
        Toolkit kit = Toolkit.getDefaultToolkit();
        // 获取屏幕的尺寸
        Dimension screenSize = kit.getScreenSize();
        // 获取屏幕的宽
        int screenWidth = screenSize.width;
        // 获取屏幕的高
        int screenHeight = screenSize.height;
        // 获取任务栏
        Insets screenInsets = kit.getScreenInsets(window.getGraphicsConfiguration());
        window.setWindowMaxX(screenWidth - windowWidth);
        window.setWindowMaxY(screenHeight - windowHeight - screenInsets.bottom);

        // 设置窗口相对于指定组件的位置:置于屏幕的中央
        // frame.setLocationRelativeTo(null);

        // 设置窗体默认在屏幕右下角
        window.setLocation(window.getWindowMaxX(), window.getWindowMaxY());
    }
}

BatteryLabel.java
package cxzgwing.label.impl;

import cxzgwing.label.LabelAdaptor;

public class BatteryLabel extends LabelAdaptor {
    private boolean display;

    public BatteryLabel(String text) {
        this.setText(text);
        this.display = true;
    }

    @Override
    public boolean isDisplay() {
        return display;
    }

    @Override
    public void setDisplay(boolean display) {
        this.display = display;
    }

}

C++创建dll

BatteryMonitor.h
#ifdef BATTERYMONITOR_EXPORTS
#define BATTERYMONITOR_API __declspec(dllexport)
#else
#define BATTERYMONITOR_API __declspec(dllimport)
#endif

extern "C" BATTERYMONITOR_API int BatteryPercent();

BatteryMonitor.cpp
#include "pch.h"
#include 
#define BATTERYMONITOR_EXPORTS
#include "BatteryMonitor.h"
#include 

using namespace std;

BATTERYMONITOR_API int BatteryPercent(){
	SYSTEM_POWER_STATUS sysPowerStatus;
	GetSystemPowerStatus(&sysPowerStatus);
	return (int)sysPowerStatus.BatteryLifePercent;
}

依赖



    4.0.0

    cxzgwing
    system-monitoring
    2.0.0

    system-monitoring

    
        UTF-8
        1.8
        1.8
    

    
        
        
            net.java.dev.jna
            jna
            5.5.0
        
    

    
        
            
                
                
                    maven-clean-plugin
                    3.1.0
                
                
                
                    maven-resources-plugin
                    3.0.2
                
                
                    maven-compiler-plugin
                    3.8.0
                
                
                    maven-surefire-plugin
                    2.22.1
                
                
                    maven-jar-plugin
                    3.0.2
                
                
                    maven-install-plugin
                    2.5.2
                
                
                    maven-deploy-plugin
                    2.8.2
                
                
                
                    maven-site-plugin
                    3.7.1
                
                
                    maven-project-info-reports-plugin
                    3.0.0
                
            
        

        
            
                maven-assembly-plugin
                
                    
                        
                            cxzgwing.App
                        
                    
                    
                        jar-with-dependencies
                    
                
                
                    
                        package
                        
                            assembly
                        
                    
                
            
        
    

Github

GitHub - cxzgwing/system-monitoring: Java Swing applet, real-time monitoring system CPU usage and memory usage.

Gitee

system-monitoring: Java Swing applet, real-time monitoring system CPU usage and memory usage.

参考链接

[1] 晨曦之光Wing.Java简易系统监视器. 2021-06-13 18:08:36
https://blog.csdn.net/qq_36533690/article/details/117881862


[2] xietansheng.Java Swing 图形界面开发(目录).2017-05-30 23:50:42
https://xiets.blog.csdn.net/article/details/72814492


[3] lucky__cc.【Swing】Java Swing JPopupMenu:弹出式菜单. 2019-08-06 22:03:34
https://blog.csdn.net/qq1437722579/article/details/98663286


[4] 艾斯曼.一个找了很久的API函数---GetSystemPowerStatus.2013-01-23 21:47:51
https://blog.csdn.net/wangqiulin123456/article/details/8535809


[5] 晨曦之光Wing.Java调用dll文件.2021-11-10 11:06:51
https://blog.csdn.net/qq_36533690/article/details/121239139

后记

此次是在之前的基础之上修改的,由两个问题引发,一是笔记本电池之前鼓包,买了新电池,想要实时查看电量。二是全屏看视频时有时候想看时间(全屏看视频时,这个窗体会一直显示)。所以就加上了显示电量和时间两个指标。

经过一番查询,发现C++可以读取电池数据,C++创建动态链接库dll文件,再通过Java使用jna调用dll文件。于是就自己干!写C++,做dll!(我发现用C++创建动态链接库dll文件会上瘾,没办法,C++太强大了)

进一步考虑到有些小伙伴可能用台式机,不需要电量信息,甚至不需要CPU使用率或者内存使用率或者时间,干脆就做成动态的算了,于是托盘菜单新增了“显示”按钮,可勾选显示的内容。

考虑到如果只显示一个参数或两个参数,原布局就很丑了,干脆加一个调整布局按钮,于是托盘菜单新增了“布局”按钮,可修改布局。

后面发现,布局和显示混合使用,情况多样,有的情况又很丑了,索性做成了动态布局,窗体根据显示的参数个数自动适配布局。

进一步开发,后来发现已采用的菜单栏的创建方案二使用JPopupMenu会导致多级菜单栏有问题,jPopupMenu.show(Component invoker, int x, int y)需要有Component(不加的话多级菜单的子菜单就弹不出来),但是系统托盘这玩意儿SystemTray它不是Component……所以想了个方法,直接新建一个Jframe,用它来和JPopupMenu绑定,Jframe和JPopupMenu大小一致,且显示和隐藏的状态一致就哦了,然后就大改了……嗯,面目全非、惨不忍睹。

然后发现新方法在弹出系统托盘菜单后,鼠标点击非菜单区域,菜单会自动消失(之前是不会的,所以用了jnativehook做全局鼠标监听,配合鼠标的位置判断,达到该效果),所以就不需要用jnativehook了。

最后为了方便和那什么,封装了Label,用了线程池。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/708220.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号