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.Color;
9   import java.awt.GridBagConstraints;
10  import java.awt.GridBagLayout;
11  import java.text.DecimalFormat;
12  import java.text.DecimalFormatSymbols;
13  import java.util.Collections;
14  import java.util.List;
15  import java.util.Locale;
16  
17  import javax.swing.JPanel;
18  import javax.swing.JTextArea;
19  import javax.swing.Timer;
20  
21  import org.jfree.chart.ChartFactory;
22  import org.jfree.chart.ChartPanel;
23  import org.jfree.chart.JFreeChart;
24  import org.jfree.chart.labels.PieSectionLabelGenerator;
25  import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
26  import org.jfree.chart.plot.PiePlot;
27  import org.jfree.chart.title.TextTitle;
28  import org.jfree.data.general.DefaultPieDataset;
29  
30  import oshi.SystemInfo;
31  import oshi.hardware.GlobalMemory;
32  import oshi.hardware.PhysicalMemory;
33  import oshi.hardware.VirtualMemory;
34  
35  /**
36   * Displays physical and virtual (swap) memory stats.
37   */
38  public class MemoryPanel extends OshiJPanel { // NOSONAR squid:S110
39  
40      private static final long serialVersionUID = 1L;
41  
42      private static final String PHYSICAL_MEMORY = "Physical Memory";
43      private static final String VIRTUAL_MEMORY = "Virtual Memory (Swap)";
44  
45      private static final String USED = "Used";
46      private static final String AVAILABLE = "Available";
47  
48      private static final DecimalFormatSymbols ROOT_SYMBOLS = DecimalFormatSymbols.getInstance(Locale.ROOT);
49  
50      public MemoryPanel(SystemInfo si) {
51          super();
52          init(si.getHardware().getMemory());
53      }
54  
55      private void init(GlobalMemory memory) {
56          DefaultPieDataset<String> physMemData = new DefaultPieDataset<>();
57          DefaultPieDataset<String> virtMemData = new DefaultPieDataset<>();
58          updateDatasets(memory, physMemData, virtMemData);
59  
60          JFreeChart physMem = ChartFactory.createPieChart(PHYSICAL_MEMORY, physMemData, true, true, false);
61          JFreeChart virtMem = ChartFactory.createPieChart(VIRTUAL_MEMORY, virtMemData, true, true, false);
62          configurePlot(physMem);
63          configurePlot(virtMem);
64          physMem.setSubtitles(Collections.singletonList(new TextTitle(updatePhysTitle(memory))));
65          virtMem.setSubtitles(Collections.singletonList(new TextTitle(updateVirtTitle(memory))));
66  
67          GridBagConstraints pmConstraints = new GridBagConstraints();
68          pmConstraints.weightx = 1d;
69          pmConstraints.weighty = 1d;
70          pmConstraints.fill = GridBagConstraints.BOTH;
71          GridBagConstraints vmConstraints = (GridBagConstraints) pmConstraints.clone();
72          vmConstraints.gridx = 1;
73          GridBagConstraints textConstraints = new GridBagConstraints();
74          textConstraints.gridy = 1;
75          textConstraints.gridwidth = 2;
76          textConstraints.fill = GridBagConstraints.BOTH;
77  
78          JPanel memoryPanel = new JPanel();
79          memoryPanel.setLayout(new GridBagLayout());
80          memoryPanel.add(new ChartPanel(physMem), pmConstraints);
81          memoryPanel.add(new ChartPanel(virtMem), vmConstraints);
82  
83          JTextArea textArea = new JTextArea(60, 20);
84          textArea.setText(updateMemoryText(memory));
85          memoryPanel.add(textArea, textConstraints);
86  
87          add(memoryPanel, BorderLayout.CENTER);
88  
89          Timer timer = new Timer(Config.REFRESH_SLOW, e -> {
90              updateDatasets(memory, physMemData, virtMemData);
91              physMem.setSubtitles(Collections.singletonList(new TextTitle(updatePhysTitle(memory))));
92              virtMem.setSubtitles(Collections.singletonList(new TextTitle(updateVirtTitle(memory))));
93              textArea.setText(updateMemoryText(memory));
94          });
95          timer.start();
96      }
97  
98      private static String updatePhysTitle(GlobalMemory memory) {
99          return memory.toString();
100     }
101 
102     private static String updateVirtTitle(GlobalMemory memory) {
103         return memory.getVirtualMemory().toString();
104     }
105 
106     private static String updateMemoryText(GlobalMemory memory) {
107         StringBuilder sb = new StringBuilder();
108         List<PhysicalMemory> pmList = memory.getPhysicalMemory();
109         for (PhysicalMemory pm : pmList) {
110             sb.append('\n').append(pm.toString());
111         }
112         return sb.toString();
113     }
114 
115     private static void updateDatasets(GlobalMemory memory, DefaultPieDataset<String> physMemData,
116             DefaultPieDataset<String> virtMemData) {
117         physMemData.setValue(USED, (double) memory.getTotal() - memory.getAvailable());
118         physMemData.setValue(AVAILABLE, memory.getAvailable());
119 
120         VirtualMemory virtualMemory = memory.getVirtualMemory();
121         virtMemData.setValue(USED, virtualMemory.getSwapUsed());
122         virtMemData.setValue(AVAILABLE, (double) virtualMemory.getSwapTotal() - virtualMemory.getSwapUsed());
123     }
124 
125     private static void configurePlot(JFreeChart chart) {
126         @SuppressWarnings("unchecked")
127         PiePlot<String> plot = (PiePlot<String>) chart.getPlot();
128         plot.setSectionPaint(USED, Color.red);
129         plot.setSectionPaint(AVAILABLE, Color.green);
130         plot.setExplodePercent(USED, 0.10);
131         plot.setSimpleLabels(true);
132 
133         PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator("{0}: {1} ({2})",
134                 new DecimalFormat("0", ROOT_SYMBOLS), new DecimalFormat("0%", ROOT_SYMBOLS));
135         plot.setLabelGenerator(labelGenerator);
136     }
137 }