View Javadoc
1   /*
2    * Copyright 2020-2023 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.demo.gui;
6   
7   import java.awt.BorderLayout;
8   import java.awt.GridBagConstraints;
9   import java.awt.GridBagLayout;
10  import java.time.LocalDateTime;
11  import java.time.ZoneId;
12  import java.util.Date;
13  
14  import javax.swing.JPanel;
15  import javax.swing.Timer;
16  
17  import org.jfree.chart.ChartFactory;
18  import org.jfree.chart.ChartPanel;
19  import org.jfree.chart.JFreeChart;
20  import org.jfree.data.time.DynamicTimeSeriesCollection;
21  import org.jfree.data.time.Second;
22  
23  import oshi.SystemInfo;
24  import oshi.hardware.CentralProcessor;
25  import oshi.hardware.CentralProcessor.TickType;
26  
27  /**
28   * Shows system and per-processor CPU usage every second in a time series chart.
29   */
30  public class ProcessorPanel extends OshiJPanel { // NOSONAR squid:S110
31  
32      private static final long serialVersionUID = 1L;
33  
34      private long[] oldTicks;
35      private long[][] oldProcTicks;
36  
37      public ProcessorPanel(SystemInfo si) {
38          super();
39          CentralProcessor cpu = si.getHardware().getProcessor();
40          oldTicks = new long[TickType.values().length];
41          oldProcTicks = new long[cpu.getLogicalProcessorCount()][TickType.values().length];
42          init(cpu);
43      }
44  
45      private void init(CentralProcessor processor) {
46  
47          GridBagConstraints sysConstraints = new GridBagConstraints();
48          sysConstraints.weightx = 1d;
49          sysConstraints.weighty = 1d;
50          sysConstraints.fill = GridBagConstraints.BOTH;
51  
52          GridBagConstraints procConstraints = (GridBagConstraints) sysConstraints.clone();
53          procConstraints.gridx = 1;
54  
55          Date date = Date.from(LocalDateTime.now(ZoneId.systemDefault()).atZone(ZoneId.systemDefault()).toInstant());
56          DynamicTimeSeriesCollection sysData = new DynamicTimeSeriesCollection(1, 60, new Second());
57          sysData.setTimeBase(new Second(date));
58          sysData.addSeries(floatArrayPercent(cpuData(processor)), 0, "All cpus");
59          JFreeChart systemCpu = ChartFactory.createTimeSeriesChart("System CPU Usage", "Time", "% CPU", sysData, true,
60                  true, false);
61  
62          double[] procUsage = procData(processor);
63          DynamicTimeSeriesCollection procData = new DynamicTimeSeriesCollection(procUsage.length, 60, new Second());
64          procData.setTimeBase(new Second(date));
65          for (int i = 0; i < procUsage.length; i++) {
66              procData.addSeries(floatArrayPercent(procUsage[i]), i, "cpu" + i);
67          }
68          JFreeChart procCpu = ChartFactory.createTimeSeriesChart("Processor CPU Usage", "Time", "% CPU", procData, true,
69                  true, false);
70  
71          JPanel cpuPanel = new JPanel();
72          cpuPanel.setLayout(new GridBagLayout());
73          cpuPanel.add(new ChartPanel(systemCpu), sysConstraints);
74          cpuPanel.add(new ChartPanel(procCpu), procConstraints);
75  
76          add(cpuPanel, BorderLayout.CENTER);
77  
78          Timer timer = new Timer(Config.REFRESH_FAST, e -> {
79              sysData.advanceTime();
80              sysData.appendData(floatArrayPercent(cpuData(processor)));
81              procData.advanceTime();
82              int newest = procData.getNewestIndex();
83              double[] procUsageData = procData(processor);
84              for (int i = 0; i < procUsageData.length; i++) {
85                  procData.addValue(i, newest, (float) (100 * procUsageData[i]));
86              }
87          });
88          timer.start();
89      }
90  
91      private static float[] floatArrayPercent(double d) {
92          float[] f = new float[1];
93          f[0] = (float) (100d * d);
94          return f;
95      }
96  
97      private double cpuData(CentralProcessor proc) {
98          double d = proc.getSystemCpuLoadBetweenTicks(oldTicks);
99          oldTicks = proc.getSystemCpuLoadTicks();
100         return d;
101     }
102 
103     private double[] procData(CentralProcessor proc) {
104         double[] p = proc.getProcessorCpuLoadBetweenTicks(oldProcTicks);
105         oldProcTicks = proc.getProcessorCpuLoadTicks();
106         return p;
107     }
108 }