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