Java simple system monitoring

Posted by jamfrag on Tue, 18 Jan 2022 21:28:25 +0100

Java simple system monitoring: real-time display of CPU utilization, memory utilization, remaining power of laptop battery and time (hour, minute and second). Create the system tray, set the system tray menu, and display the form on the top. Read battery data by jna calling dll file.

catalogue

design sketch

Function description

Projects and tools

Project description

directory structure

Core code

Window.java

Menu.java

Dll.java

AppUtil.java

BatteryLabel.java

C + + create dll

BatteryMonitor.h

BatteryMonitor.cpp

rely on

Github

Gitee

Reference link

Postscript

design sketch

Function description

  1. Java simple system monitoring: real-time display of CPU utilization, memory utilization, remaining power of laptop battery and time (hour, minute and second). CPU usage, memory usage and time are updated every second, and the remaining battery power of laptop is updated every 15 seconds.
  2. Create the system tray, set the system tray menu, and display the form on the top.
  3. System tray button:
    1. Move (or fix): Click to move or fix the form.
    2. Refresh: Click to refresh the form. It can be used when the form displays exceptions.
    3. Layout: you can change the form layout, including single column layout and double column layout. (the effect drawing is a double column layout)
    4. Display: you can select the parameters to be displayed, and check "CPU", "memory", "power" and "time".
    5. Exit program: Click to exit the program.
  4. The form cannot be moved off screen.
  5. The size of the form can be automatically adapted according to the number of parameters displayed.
  6. After clicking the system tray, a multi-level menu will pop up. When the mouse clicks the non menu area, the pop-up multi-level menu will disappear automatically. (based on JFrame+JPopupMenu)

Projects and tools

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

Project description

  1. The dynamic link library dll file generated by jna calling C + + is used to monitor the remaining battery power.
  2. Generated system-monitoring-2.0.0-jar-with-dependencies Jar needs to be associated with the images folder and batterymonitor. Jar in resources DLL file sibling. (related to the writing method of reading the relevant file path in the code)

directory structure

Core code

Due to the large number of codes, not all of them will be posted here. Please move on if you need a complete code GitHub or 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-single column layout, 2-double column layout
    private int labelLayout;

    // Maximum abscissa of form position
    private int windowMaxX;
    // Maximum ordinate of form position
    private int windowMaxY;

    public Window() throws Exception {
        // Initializes whether the form is movable
        windowMovable = new WindowMovable(false);
        font = new Font("Blackbody", Font.PLAIN, 16);
        labelLayout = LabelLayout.DOUBLE;

        // Set display label margins
        emptyBorder = new EmptyBorder(0, 5, 0, 0);
        // Set layout
        gridLayout = new GridLayout(2, 2);

        // Initialize form
        initWindow();

        // Set CPU usage Display tab
        initCpuJLabel();

        // Memory usage Display tab
        initMemJLabel();

        // Battery power percentage display label
        initBatteryJLabel();

        // Time display label
        initTimeJLabel();

        // Initialize tray menu
        initMenu();

        // Set whether the form can be moved
        setWindowDragListener();

        // Add form status listener to keep the form displayed all the time
        setWindowAlwaysShow();

        // Add system tray
        setSystemTray();

        // display
        this.setVisible(true);

        // monitor
        monitoring();
    }

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

    /**
     * Initialize the form to display CPU utilization and Mem utilization
     */
    private void initWindow() {
        // Hide taskbar icon
        this.setType(JFrame.Type.UTILITY);
        // Set window top
        this.setAlwaysOnTop(true);
        // Set borderless
        this.setUndecorated(true);
        // Set background color
        this.setBackground(new Color(0, 0, 0, 80));
        // Set form size
        this.setSize(150, 40);
        // Set layout
        this.setLayout(gridLayout);

        AppUtil.initWindowLocation(this);
    }

    private void setWindowDragListener() {
        // Set mouse monitoring. You can move the window position with the mouse
        // The first button (move / fix) in the system tray menu controls whether the form can be moved
        FrameDragListener frameDragListener = new FrameDragListener(this, windowMovable);
        this.addMouseListener(frameDragListener);
        this.addMouseMotionListener(frameDragListener);
    }

    private void initTimeJLabel() {
        // Time display label
        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() {
        // Battery power percentage display label
        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() {
        // Memory usage Display tab
        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 usage Display tab
        cpuLabel = new CpuLabel(AppUtil.getSystemCpuLoad());
        cpuLabel.setFont(font);
        cpuLabel.setForeground(Color.WHITE);
        cpuLabel.setBorder(emptyBorder);
        gridLayout.addLayoutComponent("cpuLabel", cpuLabel);
        this.add(cpuLabel);
    }

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

    /**
     * Add system tray
     */
    private void setSystemTray() throws Exception {
        try {
            if (SystemTray.isSupported()) {
                // Get the system tray of the current platform
                SystemTray tray = SystemTray.getSystemTray();

                // Load a picture for the display of tray icons
                Image image = Toolkit.getDefaultToolkit()
                        .getImage(Clock.class.getResource("/images/system-monitoring-icon.png"));

                // Create pop-up menu scheme 3 when clicking the icon: JFrame + JPopupMenu
                TrayIcon trayIcon = new TrayIcon(image, "System Monitoring");
                trayIcon.addMouseListener(new TrayIconMouseListener(menu));

                // Tray icon adaptive size
                trayIcon.setImageAutoSize(true);

                // Add tray icon to system tray
                tray.add(trayIcon);

            } else {
                throw new Exception("The current system does not support system trays");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * Add form status listener to keep the form displayed all the time
     */
    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;
    }

}

Menu.java

package cxzgwing;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Objects;

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import cxzgwing.judgement.WindowMovable;
import cxzgwing.label.LabelAdaptor;
import cxzgwing.label.impl.BatteryLabel;
import cxzgwing.label.impl.CpuLabel;
import cxzgwing.label.impl.MemoryLabel;
import cxzgwing.label.impl.TimeLabel;
import cxzgwing.utils.AppUtil;
import cxzgwing.utils.LabelLayout;

public class Menu {
    private JFrame jFrame;
    private JPopupMenu jPopupMenu;
    private Font font;

    private Window window;
    private WindowMovable windowMovable;
    private CpuLabel cpuLabel;
    private MemoryLabel memoryLabel;
    private BatteryLabel batteryLabel;
    private TimeLabel timeLabel;

    private static final int WIDTH = 75;
    private static final int HEIGHT = 110;

    public Menu(Window window, WindowMovable windowMovable, CpuLabel cpuLabel,
            MemoryLabel memoryLabel, BatteryLabel batteryLabel, TimeLabel timeLabel) {
        this.window = window;
        this.windowMovable = windowMovable;
        this.cpuLabel = cpuLabel;
        this.memoryLabel = memoryLabel;
        this.batteryLabel = batteryLabel;
        this.timeLabel = timeLabel;
        this.font = new Font("Song typeface", Font.PLAIN, 13);

        init();
        addJPopupMenuListener();
    }

    private void hiddenFrameIfShowing() {
        if (jFrame.isShowing()) {
            jFrame.setVisible(false);
        }
    }

    private void hiddenJPopupMenuIfShowing() {
        if (jPopupMenu.isShowing()) {
            jPopupMenu.setVisible(false);
        }
    }

    private void addJPopupMenuListener() {
        jPopupMenu.addPopupMenuListener(new PopupMenuListener() {
            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                hiddenFrameIfShowing();
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {}
        });
    }

    private void init() {
        setJFrame();
        setJPopupMenu();
    }

    private void setJPopupMenu() {
        jPopupMenu = new JPopupMenu();
        jPopupMenu.setSize(WIDTH, HEIGHT);

        setMovableJMenu();
        setRefreshJMenu();
        setLayoutJMenu();
        setDisplayJMenu();
        setExitJMenu();
    }

    private void setExitJMenu() {
        JMenuItem exitJMenuItem = new JMenuItem("Exit program");
        exitJMenuItem.setFont(font);
        exitJMenuItem.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.exit(0);
            }
        });
        jPopupMenu.add(exitJMenuItem);
    }

    private void setDisplayJMenu() {
        JMenu displayJMenu = new JMenu("display");
        displayJMenu.setFont(font);

        JCheckBox cpuJCheckBox = new JCheckBox("CPU");
        cpuJCheckBox.setFont(font);
        cpuJCheckBox.setSelected(true);
        cpuJCheckBox.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                stateChange(cpuLabel, cpuJCheckBox.isSelected());
            }
        });

        JCheckBox memoryJCheckBox = new JCheckBox("Memory");
        memoryJCheckBox.setFont(font);
        memoryJCheckBox.setSelected(true);
        memoryJCheckBox.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                stateChange(memoryLabel, memoryJCheckBox.isSelected());
            }
        });

        JCheckBox batteryJCheckBox = new JCheckBox("Electric quantity");
        batteryJCheckBox.setFont(font);
        batteryJCheckBox.setSelected(true);
        batteryJCheckBox.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                stateChange(batteryLabel, batteryJCheckBox.isSelected());
            }
        });

        JCheckBox timeJCheckBox = new JCheckBox("time");
        timeJCheckBox.setFont(font);
        timeJCheckBox.setSelected(true);
        timeJCheckBox.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                stateChange(timeLabel, timeJCheckBox.isSelected());
            }
        });

        displayJMenu.add(cpuJCheckBox);
        displayJMenu.add(memoryJCheckBox);
        displayJMenu.add(batteryJCheckBox);
        displayJMenu.add(timeJCheckBox);

        jPopupMenu.add(displayJMenu);
    }

    private void stateChange(LabelAdaptor label, boolean isSelected) {
        // Press the mouse in the check box and release the mouse after removing the check box area. At this time, the check box state remains unchanged and no operation is required
        if ((label.isDisplay() && isSelected) || (!label.isDisplay() && !isSelected)) {
            return;
        }
        label.setDisplay(isSelected);
        windowRemoveAll();
        reloadWindow();
        refreshWindow();
    }

    private void reloadWindow() {
        int count = getDisplayLabelCount();
        GridLayout gridLayout = updateWindowLabelLayout(count);
        reloadLabel(gridLayout);
    }

    private void reloadLabel(GridLayout gridLayout) {
        // Since the relevant data is not read when the label is not displayed, the data needs to be updated when it is displayed again
        if (cpuLabel.isDisplay()) {
            cpuLabel.setText(AppUtil.getSystemCpuLoad());
            if (LabelLayout.DOUBLE == window.getLabelLayout() && !Objects.isNull(gridLayout)) {
                gridLayout.addLayoutComponent("cpuLabel", cpuLabel);
            }
            window.add(cpuLabel);
        }
        if (memoryLabel.isDisplay()) {
            memoryLabel.setText(AppUtil.getMemoryLoad());
            if (LabelLayout.DOUBLE == window.getLabelLayout() && !Objects.isNull(gridLayout)) {
                gridLayout.addLayoutComponent("memoryLabel", memoryLabel);
            }
            window.add(memoryLabel);
        }
        if (batteryLabel.isDisplay()) {
            batteryLabel.setText(AppUtil.getBatteryPercent());
            if (LabelLayout.DOUBLE == window.getLabelLayout() && !Objects.isNull(gridLayout)) {
                gridLayout.addLayoutComponent("batteryLabel", batteryLabel);
            }
            window.add(batteryLabel);
        }
        if (timeLabel.isDisplay()) {
            timeLabel.setText(AppUtil.getTime());
            if (LabelLayout.DOUBLE == window.getLabelLayout() && !Objects.isNull(gridLayout)) {
                gridLayout.addLayoutComponent("timeLabel", timeLabel);
            }
            window.add(timeLabel);
        }
    }

    private int getDisplayLabelCount() {
        int count = 0;
        if (cpuLabel.isDisplay()) {
            count++;
        }
        if (memoryLabel.isDisplay()) {
            count++;
        }
        if (batteryLabel.isDisplay()) {
            count++;
        }
        if (timeLabel.isDisplay()) {
            count++;
        }
        return count;
    }

    private GridLayout updateWindowLabelLayout(int count) {
        GridLayout gridLayout = null;
        if (LabelLayout.SINGLE == window.getLabelLayout()) {
            // Single column layout
            window.setSize(window.getWidth(), 20 * count);
        } else if (LabelLayout.DOUBLE == window.getLabelLayout()) {
            // Double column layout
            switch (count) {
                case 1:
                    window.setLayout(gridLayout = new GridLayout(1, 1));
                    window.setSize(75, 20);
                    break;
                case 2:
                    window.setLayout(gridLayout = new GridLayout(1, 2));
                    window.setSize(150, 20);
                    break;
                case 3:
                case 4:
                    window.setLayout(gridLayout = new GridLayout(2, 2));
                    window.setSize(150, 40);
                    break;
                default:
                    window.setLayout(gridLayout = new GridLayout(2, 2));
                    window.setSize(150, 40);
            }
        }
        AppUtil.initWindowLocation(window);
        return gridLayout;
    }

    private void windowRemoveAll() {
        window.remove(cpuLabel);
        window.remove(memoryLabel);
        window.remove(batteryLabel);
        window.remove(timeLabel);
    }

    private void setLayoutJMenu() {
        JMenu layoutJMenu = new JMenu("layout");
        layoutJMenu.setFont(font);
        JMenuItem singleJMenuItem = new JMenuItem("Single column layout");
        singleJMenuItem.setFont(font);
        singleJMenuItem.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                window.setLabelLayout(LabelLayout.SINGLE);
                window.setSize(85, 80);
                window.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 1));
                reloadWindow();
                AppUtil.initWindowLocation(window);
                refreshWindow();
            }
        });
        JMenuItem doubleJMenuItem = new JMenuItem("Double column layout");
        doubleJMenuItem.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                window.setLabelLayout(LabelLayout.DOUBLE);
                window.setSize(150, 40);
                window.setLayout(new GridLayout(2, 2));
                reloadWindow();
                AppUtil.initWindowLocation(window);
                refreshWindow();
            }
        });
        doubleJMenuItem.setFont(font);
        layoutJMenu.add(singleJMenuItem);
        layoutJMenu.add(doubleJMenuItem);
        jPopupMenu.add(layoutJMenu);
    }

    private void setRefreshJMenu() {
        JMenuItem refreshJMenuItem = new JMenuItem("Refresh");
        refreshJMenuItem.setFont(font);
        refreshJMenuItem.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                refreshWindow();
            }
        });
        jPopupMenu.add(refreshJMenuItem);
    }

    private void refreshWindow() {
        window.setVisible(false);
        window.setVisible(true);
    }

    private void setMovableJMenu() {
        JMenuItem movableJMenuItem = new JMenuItem("move");
        movableJMenuItem.setFont(font);
        movableJMenuItem.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                windowMovable.setValue(!windowMovable.getValue());
                if (windowMovable.isTrue()) {
                    movableJMenuItem.setText("fixed");
                } else {
                    movableJMenuItem.setText("move");
                }
            }
        });
        jPopupMenu.add(movableJMenuItem);
    }

    private void setJFrame() {
        this.jFrame = new JFrame();
        // Set borderless
        jFrame.setUndecorated(true);
        // Hide taskbar icon
        jFrame.setType(JFrame.Type.UTILITY);
        // Set window top
        jFrame.setAlwaysOnTop(true);
        // Set background color
        jFrame.setBackground(new Color(255, 255, 255, 255));
        // Set form size
        jFrame.setSize(WIDTH, HEIGHT);
        // Set layout
        jFrame.setLayout(new GridLayout(5, 1));

    }

    public void display(MouseEvent mouseEvent) {
        hiddenFrameIfShowing();
        hiddenJPopupMenuIfShowing();
        jFrame.setLocation(mouseEvent.getX() - WIDTH, mouseEvent.getY() - HEIGHT);
        jFrame.setVisible(true);
        jPopupMenu.show(jFrame, 0, 0);
        // System.out.println("Width=" + jPopupMenu.getWidth() + "Height=" +
        // jPopupMenu.getHeight());
    }

}

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) {
        // Get form width
        int windowWidth = window.getWidth();
        // Get form height
        int windowHeight = window.getHeight();
        // Define Toolkit
        Toolkit kit = Toolkit.getDefaultToolkit();
        // Gets the size of the screen
        Dimension screenSize = kit.getScreenSize();
        // Gets the width of the screen
        int screenWidth = screenSize.width;
        // Gets the height of the screen
        int screenHeight = screenSize.height;
        // Get taskbar
        Insets screenInsets = kit.getScreenInsets(window.getGraphicsConfiguration());
        window.setWindowMaxX(screenWidth - windowWidth);
        window.setWindowMaxY(screenHeight - windowHeight - screenInsets.bottom);

        // Sets the position of the window relative to the specified component: placed in the center of the screen
        // frame.setLocationRelativeTo(null);

        // Set the default form in the lower right corner of the screen
        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 + + create 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 <iostream>
#define BATTERYMONITOR_EXPORTS
#include "BatteryMonitor.h"
#include <Windows.h>

using namespace std;

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

rely on

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cxzgwing</groupId>
    <artifactId>system-monitoring</artifactId>
    <version>2.0.0</version>

    <name>system-monitoring</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.5.0</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>cxzgwing.App</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>assembly</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

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.

Reference link

[1] Morning light wing Java simple system monitor 2021-06-13 18:08:36
https://blog.csdn.net/qq_36533690/article/details/117881862


[2] xietansheng.Java Swing graphical interface development (directory). 2017-05-30 23:50:42
https://xiets.blog.csdn.net/article/details/72814492


[3] lucky__cc. [Swing] Java Swing JPopupMenu: pop up menu 2019-08-06 22:03:34
https://blog.csdn.net/qq1437722579/article/details/98663286


[4] Eisman An API function that has been found for a long time -- getsystempowerstatus 2013-01-23 21:47:51
https://blog.csdn.net/wangqiulin123456/article/details/8535809


[5] Morning light wing Java call dll file. 2021-11-10 11:06:51
https://blog.csdn.net/qq_36533690/article/details/121239139

Postscript

This time, it was modified on the basis of the previous. It was caused by two problems. One was that the laptop battery was bulging before and bought a new battery to check the power in real time. Second, sometimes I want to see the time when watching the video in full screen (this window will always be displayed when watching the video in full screen). Therefore, two indicators of display power and time are added.

After some inquiry, it is found that C + + can read battery data, C + + creates dynamic link library dll file, and then calls dll file using jna through Java. So do it yourself! Write c + +, do dll! (I find it addictive to use C + + to create dll files of dynamic link library. I can't help it. C + + is too powerful)

Further, considering that some small partners may use desktop computers and do not need power information, or even CPU utilization or memory utilization or time, they simply make it dynamic, so the "display" button is added to the tray menu to check the displayed content.

Considering that if only one or two parameters are displayed, the original layout will be ugly. Simply add an adjust layout button, so the "layout" button is added in the tray menu to modify the layout.

Later, it was found that the mixed use of layout and display has a variety of situations, and some situations are ugly. It was simply made into a dynamic layout, and the form automatically adapts to the layout according to the number of displayed parameters.

After further development, it was found that the adopted menu bar creation scheme II. Using JPopupMenu will lead to problems with multi-level menu bars, JPopupMenu Show (Component invoker, int x, int y) requires a Component (if it is not added, the submenu of the multi-level menu will not pop up), but the system tray is SystemTray. It is not a Component... So I think of a way to directly create a JFrame and bind it with JPopupMenu. JFrame and JPopupMenu are the same size, and the displayed and hidden states are the same, Then it changed... Well, it was beyond recognition and terrible.

Then it is found that after the system tray menu pops up, click the non menu area with the mouse, and the menu will disappear automatically (it was not before, so jnativehook is used for global mouse monitoring, and the effect is achieved by matching the mouse position judgment). Therefore, jnativehook is not needed.

Finally, in order to facilitate and what, the Label is encapsulated and the thread pool is used.

Topics: Java Back-end cpu swing