001: package tijmp.ui;
002:
003: import java.awt.Color;
004: import java.awt.Dimension;
005: import java.awt.Graphics;
006: import java.awt.Image;
007: import java.awt.Insets;
008: import java.awt.event.ActionEvent;
009: import java.awt.event.ActionListener;
010: import java.lang.management.MemoryMXBean;
011: import java.lang.management.MemoryUsage;
012: import javax.swing.BorderFactory;
013: import javax.swing.JPanel;
014: import javax.swing.Timer;
015:
016: /** A panel that shows a graph of the current memory usage.
017: */
018: public class MemoryGraph extends JPanel implements ActionListener {
019: private MemoryMXBean mbean;
020: private long[] usage = null;
021: private Image image = null;
022: private int currentCol = 0;
023: private int maxColumns = -1;
024: private long currentMaxCommitted = 0;
025: private Timer timer;
026:
027: public MemoryGraph(MemoryMXBean mbean) {
028: this .mbean = mbean;
029: setPreferredSize(new Dimension(500, 100));
030: setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
031: setOpaque(true);
032: setBackground(Color.WHITE);
033: }
034:
035: public void start() {
036: timer = new Timer(1000, this );
037: timer.start();
038: }
039:
040: public void stop() {
041: timer.stop();
042: }
043:
044: public void actionPerformed(ActionEvent e) {
045: if (!isVisible())
046: return;
047: Insets insets = getInsets();
048: int currentWidth = getWidth() - insets.left - insets.right;
049: int currentHeight = getHeight() - insets.top - insets.bottom;
050: if (usage == null || usage.length / 2 != currentWidth) {
051: // TODO: copy old contents...
052: usage = new long[currentWidth * 2];
053: image = createImage(currentWidth, currentHeight);
054: currentCol = 0;
055: maxColumns = currentWidth;
056: }
057: MemoryUsage heapUsage = mbean.getHeapMemoryUsage();
058: int currentLine = currentCol % maxColumns;
059: int index = currentLine * 2;
060: usage[index] = heapUsage.getUsed();
061: usage[index + 1] = heapUsage.getCommitted();
062: Graphics g = null;
063: try {
064: g = image.getGraphics();
065: if (usage[index + 1] > currentMaxCommitted) {
066: currentMaxCommitted = usage[index + 1];
067: doFullRedraw(g, insets, currentHeight, currentWidth);
068: } else {
069: drawUsage(g, index, currentLine, currentHeight);
070: }
071: } finally {
072: if (g != null)
073: g.dispose();
074: }
075: try {
076: g = getGraphics();
077: paintComponent(g);
078: } finally {
079: if (g != null)
080: g.dispose();
081: }
082: currentCol++;
083: }
084:
085: public void paintComponent(Graphics g) {
086: Insets insets = getInsets();
087: int currentLine = currentCol % maxColumns;
088: if (currentCol < maxColumns || currentLine == 0) {
089: g.drawImage(image, insets.left, insets.top, null);
090: } else {
091: int yMax = image.getHeight(null) + insets.top;
092: int startSecond = insets.left + maxColumns - currentLine;
093: g.drawImage(image, insets.left, insets.top, startSecond,
094: yMax, currentLine, 0, maxColumns, yMax, null);
095: g.drawImage(image, startSecond, insets.top, startSecond
096: + currentLine, yMax, 0, 0, currentLine, yMax, null);
097: }
098: }
099:
100: private void doFullRedraw(Graphics g, Insets insets,
101: int currentHeight, int currentWidth) {
102: g.setColor(getBackground());
103: g
104: .fillRect(insets.left, insets.top, currentWidth,
105: currentHeight);
106: for (int col = 0; col < currentWidth; col++)
107: drawUsage(g, col * 2, col, currentHeight);
108: }
109:
110: private void drawUsage(Graphics g, int index, int col,
111: int currentHeight) {
112: double cmc = currentMaxCommitted;
113: if (usage[index + 1] == 0)
114: return; // no commited memory = no value for column.
115: int endH = (int) (currentHeight * (1 - usage[index] / cmc));
116: int endC = (int) (currentHeight * (1 - usage[index + 1] / cmc));
117: g.setColor(Color.BLUE);
118: g.drawLine(col, currentHeight, col, endH);
119: g.setColor(Color.PINK);
120: g.drawLine(col, endH, col, endC);
121: g.setColor(getBackground());
122: g.drawLine(col, endC, col, 0);
123: }
124: }
|