View Javadoc

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 			// Draw allocated and used strings
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 			// Calculate remaining size
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 			// Memory Free
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 			// Memory Used
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 			// Draw History Graph
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 			// Draw animated column movement
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 						// throw out oldest point
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 }