1 /* 2 * 3 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of Oracle nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package java2d; 33 34 35 import static java.awt.Color.BLACK; 36 import static java.awt.Color.GREEN; 37 import static java.awt.Color.YELLOW; 38 import java.awt.BorderLayout; 39 import java.awt.Color; 40 import java.awt.Dimension; 41 import java.awt.Font; 42 import java.awt.FontMetrics; 43 import java.awt.Graphics; 44 import java.awt.Graphics2D; 45 import java.awt.Rectangle; 46 import java.awt.event.MouseAdapter; 47 import java.awt.event.MouseEvent; 48 import java.awt.event.WindowAdapter; 49 import java.awt.event.WindowEvent; 50 import java.awt.event.WindowListener; 51 import java.awt.geom.Line2D; 52 import java.awt.geom.Rectangle2D; 53 import java.awt.image.BufferedImage; 54 import java.util.Date; 55 import javax.swing.JCheckBox; 56 import javax.swing.JFrame; 57 import javax.swing.JLabel; 58 import javax.swing.JPanel; 59 import javax.swing.JTextField; 60 import javax.swing.border.EtchedBorder; 61 import javax.swing.border.TitledBorder; 62 63 64 /** 65 * Tracks Memory allocated & used, displayed in graph form. 66 */ 67 @SuppressWarnings("serial") 68 public class MemoryMonitor extends JPanel { 69 70 private final JCheckBox dateStampCB = new JCheckBox("Output Date Stamp"); 71 public Surface surf; 72 JPanel controls; 73 boolean doControls; 74 JTextField tf; 75 76 public MemoryMonitor() { 77 setLayout(new BorderLayout()); 78 setBorder(new TitledBorder(new EtchedBorder(), "Memory Monitor")); 79 add(surf = new Surface()); 80 controls = new JPanel(); 81 controls.setPreferredSize(new Dimension(135, 80)); 82 Font font = new Font(Font.SERIF, Font.PLAIN, 10); 83 JLabel label = new JLabel("Sample Rate"); 84 label.setFont(font); 85 label.setForeground(BLACK); 86 controls.add(label); 87 tf = new JTextField("1000"); 88 tf.setPreferredSize(new Dimension(45, 20)); 89 controls.add(tf); 90 controls.add(label = new JLabel("ms")); 91 label.setFont(font); 92 label.setForeground(BLACK); 93 controls.add(dateStampCB); 94 dateStampCB.setFont(font); 95 addMouseListener(new MouseAdapter() { 96 97 @Override 98 public void mouseClicked(MouseEvent e) { 99 removeAll(); 100 if ((doControls = !doControls)) { 101 surf.stop(); 102 add(controls); 103 } else { 104 try { 105 surf.sleepAmount = Long.parseLong(tf.getText().trim()); 106 } catch (Exception ex) { 107 } 108 surf.start(); 109 add(surf); 110 } 111 revalidate(); 112 repaint(); 113 } 114 }); 115 } 116 117 118 public class Surface extends JPanel implements Runnable { 119 120 public Thread thread; 121 public long sleepAmount = 1000; 122 private int w, h; 123 private BufferedImage bimg; 124 private Graphics2D big; 125 private Font font = new Font(Font.SERIF, Font.PLAIN, 11); 126 private Runtime r = Runtime.getRuntime(); 127 private int columnInc; 128 private int pts[]; 129 private int ptNum; 130 private int ascent, descent; 131 private Rectangle graphOutlineRect = new Rectangle(); 132 private Rectangle2D mfRect = new Rectangle2D.Float(); 133 private Rectangle2D muRect = new Rectangle2D.Float(); 134 private Line2D graphLine = new Line2D.Float(); 135 private Color graphColor = new Color(46, 139, 87); 136 private Color mfColor = new Color(0, 100, 0); 137 private String usedStr; 138 139 public Surface() { 140 setBackground(BLACK); 141 addMouseListener(new MouseAdapter() { 142 143 @Override 144 public void mouseClicked(MouseEvent e) { 145 if (thread == null) { 146 start(); 147 } else { 148 stop(); 149 } 150 } 151 }); 152 } 153 154 @Override 155 public Dimension getMinimumSize() { 156 return getPreferredSize(); 157 } 158 159 @Override 160 public Dimension getMaximumSize() { 161 return getPreferredSize(); 162 } 163 164 @Override 165 public Dimension getPreferredSize() { 166 return new Dimension(135, 80); 167 } 168 169 @Override 170 public void paint(Graphics g) { 171 172 if (big == null) { 173 return; 174 } 175 176 big.setBackground(getBackground()); 177 big.clearRect(0, 0, w, h); 178 179 float freeMemory = r.freeMemory(); 180 float totalMemory = r.totalMemory(); 181 182 // .. Draw allocated and used strings .. 183 big.setColor(GREEN); 184 big.drawString(String.valueOf((int) totalMemory / 1024) 185 + "K allocated", 4.0f, ascent + 0.5f); 186 usedStr = String.valueOf(((int) (totalMemory - freeMemory)) / 1024) 187 + "K used"; 188 big.drawString(usedStr, 4, h - descent); 189 190 // Calculate remaining size 191 float ssH = ascent + descent; 192 float remainingHeight = (h - (ssH * 2) - 0.5f); 193 float blockHeight = remainingHeight / 10; 194 float blockWidth = 20.0f; 195 196 // .. Memory Free .. 197 big.setColor(mfColor); 198 int MemUsage = (int) ((freeMemory / totalMemory) * 10); 199 int i = 0; 200 for (; i < MemUsage; i++) { 201 mfRect.setRect(5, ssH + i * blockHeight, 202 blockWidth, blockHeight - 1); 203 big.fill(mfRect); 204 } 205 206 // .. Memory Used .. 207 big.setColor(GREEN); 208 for (; i < 10; i++) { 209 muRect.setRect(5, ssH + i * blockHeight, 210 blockWidth, blockHeight - 1); 211 big.fill(muRect); 212 } 213 214 // .. Draw History Graph .. 215 big.setColor(graphColor); 216 int graphX = 30; 217 int graphY = (int) ssH; 218 int graphW = w - graphX - 5; 219 int graphH = (int) remainingHeight; 220 graphOutlineRect.setRect(graphX, graphY, graphW, graphH); 221 big.draw(graphOutlineRect); 222 223 int graphRow = graphH / 10; 224 225 // .. Draw row .. 226 for (int j = graphY; j <= graphH + graphY; j += graphRow) { 227 graphLine.setLine(graphX, j, graphX + graphW, j); 228 big.draw(graphLine); 229 } 230 231 // .. Draw animated column movement .. 232 int graphColumn = graphW / 15; 233 234 if (columnInc == 0) { 235 columnInc = graphColumn; 236 } 237 238 for (int j = graphX + columnInc; j < graphW + graphX; j += 239 graphColumn) { 240 graphLine.setLine(j, graphY, j, graphY + graphH); 241 big.draw(graphLine); 242 } 243 244 --columnInc; 245 246 if (pts == null) { 247 pts = new int[graphW]; 248 ptNum = 0; 249 } else if (pts.length != graphW) { 250 int tmp[] = null; 251 if (ptNum < graphW) { 252 tmp = new int[ptNum]; 253 System.arraycopy(pts, 0, tmp, 0, tmp.length); 254 } else { 255 tmp = new int[graphW]; 256 System.arraycopy(pts, pts.length - tmp.length, tmp, 0, 257 tmp.length); 258 ptNum = tmp.length - 2; 259 } 260 pts = new int[graphW]; 261 System.arraycopy(tmp, 0, pts, 0, tmp.length); 262 } else { 263 big.setColor(YELLOW); 264 pts[ptNum] = 265 (int) (graphY + graphH * (freeMemory / totalMemory)); 266 for (int j = graphX + graphW - ptNum, k = 0; k < ptNum; k++, j++) { 267 if (k != 0) { 268 if (pts[k] != pts[k - 1]) { 269 big.drawLine(j - 1, pts[k - 1], j, pts[k]); 270 } else { 271 big.fillRect(j, pts[k], 1, 1); 272 } 273 } 274 } 275 if (ptNum + 2 == pts.length) { 276 // throw out oldest point 277 for (int j = 1; j < ptNum; j++) { 278 pts[j - 1] = pts[j]; 279 } 280 --ptNum; 281 } else { 282 ptNum++; 283 } 284 } 285 g.drawImage(bimg, 0, 0, this); 286 } 287 288 public void start() { 289 thread = new Thread(this); 290 thread.setPriority(Thread.MIN_PRIORITY); 291 thread.setName("MemoryMonitor"); 292 thread.start(); 293 } 294 295 public synchronized void stop() { 296 thread = null; 297 notify(); 298 } 299 300 @Override 301 @SuppressWarnings("SleepWhileHoldingLock") 302 public void run() { 303 304 Thread me = Thread.currentThread(); 305 306 while (thread == me && !isShowing() || getSize().width == 0) { 307 try { 308 Thread.sleep(500); 309 } catch (InterruptedException e) { 310 return; 311 } 312 } 313 314 while (thread == me && isShowing()) { 315 Dimension d = getSize(); 316 if (d.width != w || d.height != h) { 317 w = d.width; 318 h = d.height; 319 bimg = (BufferedImage) createImage(w, h); 320 big = bimg.createGraphics(); 321 big.setFont(font); 322 FontMetrics fm = big.getFontMetrics(font); 323 ascent = fm.getAscent(); 324 descent = fm.getDescent(); 325 } 326 repaint(); 327 try { 328 Thread.sleep(sleepAmount); 329 } catch (InterruptedException e) { 330 break; 331 } 332 if (dateStampCB.isSelected()) { 333 System.out.println(new Date().toString() + " " + usedStr); 334 } 335 } 336 thread = null; 337 } 338 } 339 340 public static void main(String s[]) { 341 final MemoryMonitor demo = new MemoryMonitor(); 342 WindowListener l = new WindowAdapter() { 343 344 @Override 345 public void windowClosing(WindowEvent e) { 346 System.exit(0); 347 } 348 349 @Override 350 public void windowDeiconified(WindowEvent e) { 351 demo.surf.start(); 352 } 353 354 @Override 355 public void windowIconified(WindowEvent e) { 356 demo.surf.stop(); 357 } 358 }; 359 JFrame f = new JFrame("J2D Demo - MemoryMonitor"); 360 f.addWindowListener(l); 361 f.getContentPane().add("Center", demo); 362 f.pack(); 363 f.setSize(new Dimension(200, 200)); 364 f.setVisible(true); 365 demo.surf.start(); 366 } 367 }