1 package com.eviware.soapui.support.monitor;
2
3 import javax.swing.*;
4 import java.awt.*;
5 import java.awt.event.ActionEvent;
6 import java.awt.geom.Line2D;
7 import java.awt.geom.Rectangle2D;
8 import java.awt.image.BufferedImage;
9
10 /***
11 * @author Angelo De Caro
12 */
13 public class MonitorPanel extends JPanel {
14 public Surface surf;
15
16 public MonitorPanel(MonitorSource monitorSource) {
17 setLayout(new BorderLayout());
18 add(surf = createSurface());
19 setMonitorSource(monitorSource);
20
21 JPopupMenu popup = new JPopupMenu();
22 popup.add( new GCAction() );
23
24 setComponentPopupMenu( popup );
25 }
26
27 public void start() {
28 surf.start();
29 }
30
31 public void stop() {
32 surf.stop();
33 }
34
35 public MonitorSource getMonitorSource() {
36 return surf.getMonitorSource();
37 }
38
39 public void setMonitorSource(MonitorSource monitorSource) {
40 surf.setMonitorSource(monitorSource);
41 }
42
43 protected Surface createSurface() {
44 return new Surface(null);
45 }
46
47 protected class Surface extends JPanel implements Runnable {
48 private Thread thread;
49 private MonitorSource monitorSource;
50
51 private long sleepAmount = 1000;
52
53 private int w, h;
54 private BufferedImage backImage;
55 private Graphics2D backImageGrfx;
56
57 private Font font = new Font("Times New Roman", Font.PLAIN, 11);
58 private int columnInc;
59
60 private double[] points;
61 private int validPoints;
62
63 private int ascent, descent;
64
65 private Rectangle2D mfRect = new Rectangle2D.Float();
66 private Rectangle2D muRect = new Rectangle2D.Float();
67 private Line2D graphLine = new Line2D.Float();
68 private Color graphColor = new Color(46, 139, 87);
69 private Color mfColor = new Color(0, 100, 0);
70
71 public Surface(MonitorSource monitorSource) {
72 this.monitorSource = monitorSource;
73 setBackground(Color.black);
74 }
75
76 public void paint(Graphics g) {
77 Dimension d = getSize();
78
79 if (d.width != w || d.height != h) {
80 w = d.width;
81 h = d.height;
82
83 backImage = (BufferedImage) createImage(w, h);
84 backImageGrfx = backImage.createGraphics();
85 backImageGrfx.setFont(font);
86
87 FontMetrics fm = backImageGrfx.getFontMetrics(font);
88 ascent = fm.getAscent();
89 descent = fm.getDescent();
90 }
91
92 backImageGrfx.setBackground(Color.DARK_GRAY);
93 backImageGrfx.clearRect(0, 0, w, h);
94
95 float totalMemory = monitorSource.getTotal();
96 float usedMemory = monitorSource.getUsed();
97 float freeMemory = totalMemory - usedMemory;
98
99
100 backImageGrfx.setColor(Color.green);
101 backImageGrfx.drawString(String.valueOf((int) totalMemory >> 10) + "K allocated", 4.0f, (float) ascent + 0.5f);
102 String usedStr = String.valueOf(((int) usedMemory) >> 10) + "K used";
103 backImageGrfx.drawString(usedStr, 4, h - descent);
104
105
106 float ssH = ascent + descent;
107 float remainingHeight = (h - ssH * 2 - 0.5f);
108 float blockHeight = remainingHeight / 10;
109 float blockWidth = 20.0f;
110
111
112 backImageGrfx.setColor(mfColor);
113 int MemUsage = (int) (freeMemory / totalMemory * 10);
114 int i = 0;
115 for (; i < MemUsage; i++) {
116 mfRect.setRect(5, ssH + i * blockHeight, blockWidth, blockHeight - 1);
117 backImageGrfx.fill(mfRect);
118 }
119
120
121 backImageGrfx.setColor(Color.green);
122 for (; i < 10; i++) {
123 muRect.setRect(5, ssH + i * blockHeight, blockWidth, blockHeight - 1);
124 backImageGrfx.fill(muRect);
125 }
126
127
128 backImageGrfx.setColor(graphColor);
129 int graphX = 30;
130 int graphY = (int) ssH;
131 int graphW = w - graphX - 5;
132 if( graphW < 0 )
133 graphW = 0;
134 int graphH = (int) (ssH + (9 * blockHeight) + blockHeight - 1);
135
136 i = 0;
137 for (; i < 10; i++) {
138 muRect.setRect(graphX, ssH + i * blockHeight - 1, graphW, blockHeight);
139 backImageGrfx.draw(muRect);
140 }
141
142
143 int graphColumn = graphW / 15;
144
145 if (columnInc == 0) {
146 columnInc = graphColumn;
147 }
148
149 for (int j = graphX + columnInc; j < graphW + graphX; j += graphColumn) {
150 graphLine.setLine(j, graphY, j, ssH + i * blockHeight - 1);
151 backImageGrfx.draw(graphLine);
152 }
153
154 --columnInc;
155
156 if (points == null) {
157 points = new double[graphW];
158 validPoints = 0;
159 } else if (points.length != graphW) {
160 double[] tmp;
161 if (validPoints < graphW) {
162 tmp = new double[validPoints];
163 System.arraycopy(points, 0, tmp, 0, tmp.length);
164 } else {
165 tmp = new double[graphW];
166 System.arraycopy(points, points.length - tmp.length, tmp, 0, tmp.length);
167 validPoints = tmp.length - 2;
168 }
169 points = new double[graphW];
170 System.arraycopy(tmp, 0, points, 0, tmp.length);
171 } else {
172 backImageGrfx.setColor(Color.yellow);
173 int x = w - 5;
174 int sum = graphH - (ascent + descent);
175
176 for (int j = x - validPoints, k = 0; k < validPoints; k++, j++) {
177 if (k != 0) {
178 if (points[k] != points[k - 1]) {
179 backImageGrfx.drawLine(j - 1, graphY + (int) (sum * points[k - 1]), j, graphY + (int) (sum * points[k]));
180 } else {
181 backImageGrfx.fillRect(j, graphY + (int) (sum * points[k]), 1, 1);
182 }
183 }
184 }
185 }
186
187 g.drawImage(backImage, 0, 0, this);
188 }
189
190 public void run() {
191 while (thread != null) {
192 float totalMemory = monitorSource.getTotal();
193 float usedMemory = monitorSource.getUsed();
194 float freeMemory = totalMemory - usedMemory;
195
196 if (points == null) {
197 points = new double[1];
198 validPoints = 0;
199 } else if (points.length < validPoints + 1) {
200 double[] tmp;
201
202 int graphW = validPoints +1;
203 if (validPoints < graphW) {
204 tmp = new double[validPoints];
205 System.arraycopy(points, 0, tmp, 0, tmp.length);
206 } else {
207 tmp = new double[graphW];
208 System.arraycopy(points, points.length - tmp.length, tmp, 0, tmp.length);
209 validPoints = tmp.length - 2;
210 }
211 points = new double[graphW];
212 System.arraycopy(tmp, 0, points, 0, tmp.length);
213 } else {
214 points[validPoints] = (freeMemory / totalMemory);
215 if (validPoints + 2 == points.length) {
216
217 System.arraycopy(points, 1, points, 0, validPoints);
218 --validPoints;
219 } else {
220 validPoints++;
221 }
222 }
223
224 repaint();
225
226 try {
227 Thread.sleep(sleepAmount);
228 } catch (InterruptedException e) {
229 break;
230 }
231 }
232 }
233
234 public void start() {
235 if (monitorSource == null)
236 throw new IllegalStateException("Monitor Source cannot be null.");
237
238 thread = new Thread(this);
239 thread.setPriority(Thread.MIN_PRIORITY);
240 thread.setDaemon(true);
241 thread.setName("MemoryMonitor");
242 thread.start();
243 }
244
245 public synchronized void stop() {
246 thread = null;
247 notify();
248 }
249
250 public MonitorSource getMonitorSource() {
251 return monitorSource;
252 }
253
254 public void setMonitorSource(MonitorSource monitorSource) {
255 this.monitorSource = monitorSource;
256 }
257
258 public Dimension getMinimumSize() {
259 return getPreferredSize();
260 }
261
262 public Dimension getMaximumSize() {
263 return getPreferredSize();
264 }
265
266 public Dimension getPreferredSize() {
267 return new Dimension(135, 80);
268 }
269 }
270
271 private class GCAction extends AbstractAction
272 {
273 private GCAction()
274 {
275 super( "Run GC" );
276 putValue( SHORT_DESCRIPTION, "Runs finalization and garbage collector" );
277 }
278
279 public void actionPerformed( ActionEvent e )
280 {
281 System.runFinalization();
282 Runtime.getRuntime().gc();
283 }
284 }
285 }