001/*
002 * Copyright (c) 2002 Sun Microsystems, Inc. All  Rights Reserved.
003 *
004 * Redistribution and use in source and binary forms, with or without
005 * modification, are permitted provided that the following conditions
006 * are met:
007 *
008 * -Redistributions of source code must retain the above copyright
009 *  notice, this list of conditions and the following disclaimer.
010 *
011 * -Redistribution in binary form must reproduct the above copyright
012 *  notice, this list of conditions and the following disclaimer in
013 *  the documentation and/or other materials provided with the distribution.
014 *
015 * Neither the name of Sun Microsystems, Inc. or the names of contributors
016 * may be used to endorse or promote products derived from this software
017 * without specific prior written permission.
018 *
019 * This software is provided "AS IS," without a warranty of any kind. ALL
020 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
021 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
022 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT
023 * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
024 * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
025 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
026 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
027 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
028 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
029 * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
030 *
031 * You acknowledge that Software is not designed, licensed or intended for
032 * use in the design, construction, operation or maintenance of any nuclear
033 * facility.
034 */
035
036/*
037 * @(#)MemoryMonitor.java   1.31 02/06/13
038 */
039
040package org.biojava.nbio.structure.align.gui;
041
042import javax.swing.*;
043import javax.swing.border.EtchedBorder;
044import javax.swing.border.TitledBorder;
045import java.awt.*;
046import java.awt.event.*;
047import java.awt.geom.Line2D;
048import java.awt.geom.Rectangle2D;
049import java.awt.image.BufferedImage;
050import java.util.Date;
051
052
053/**
054 * Tracks Memory allocated & used, displayed in graph form.
055 */
056public class MemoryMonitor extends JPanel {
057
058        static JCheckBox dateStampCB = new JCheckBox("Output Date Stamp");
059        public Surface surf;
060        JPanel controls;
061        boolean doControls;
062        JTextField tf;
063
064        public static final long serialVersionUID = 56289234782130l;
065
066        public MemoryMonitor() {
067                setLayout(new BorderLayout());
068                setBorder(new TitledBorder(new EtchedBorder(), "Memory Monitor"));
069                add(surf = new Surface());
070                controls = new JPanel();
071                controls.setPreferredSize(new Dimension(135,80));
072                Font font = new Font("serif", Font.PLAIN, 10);
073                JLabel label = new JLabel("Sample Rate");
074                label.setFont(font);
075                label.setForeground(Color.black);
076                controls.add(label);
077                tf = new JTextField("1000");
078                tf.setPreferredSize(new Dimension(45,20));
079                controls.add(tf);
080                controls.add(label = new JLabel("ms"));
081                label.setFont(font);
082                label.setForeground(Color.black);
083                controls.add(dateStampCB);
084                dateStampCB.setFont(font);
085                addMouseListener(new MouseAdapter() {
086                        @Override
087                        public void mouseClicked(MouseEvent e) {
088                                removeAll();
089                                if ((doControls = !doControls)) {
090                                        surf.stop();
091                                        add(controls);
092                                } else {
093                                        try {
094                                                surf.sleepAmount = Long.parseLong(tf.getText().trim());
095                                        } catch (Exception ex) {}
096                                        surf.start();
097                                        add(surf);
098                                }
099                                validate();
100                                repaint();
101                        }
102                });
103        }
104
105
106        public class Surface extends JPanel implements Runnable {
107
108                public static final long serialVersionUID = 2387409854370432908l;
109
110                public Thread thread;
111                public long sleepAmount = 1000;
112                private int w, h;
113                private BufferedImage bimg;
114                private Graphics2D big;
115                private Font font = new Font("Times New Roman", Font.PLAIN, 11);
116                private Runtime r = Runtime.getRuntime();
117                private int columnInc;
118                private int[] pts;
119                private int ptNum;
120                private int ascent, descent;
121                //private float freeMemory, totalMemory;
122                private Rectangle graphOutlineRect = new Rectangle();
123                private Rectangle2D mfRect = new Rectangle2D.Float();
124                private Rectangle2D muRect = new Rectangle2D.Float();
125                private Line2D graphLine = new Line2D.Float();
126                private Color graphColor = new Color(46, 139, 87);
127                private Color mfColor = new Color(0, 100, 0);
128                private String usedStr;
129
130
131                public Surface() {
132                        setBackground(Color.black);
133                        addMouseListener(new MouseAdapter() {
134                                @Override
135                                public void mouseClicked(MouseEvent e) {
136                                        if (thread == null) start(); else stop();
137                                }
138                        });
139                }
140
141                @Override
142                public Dimension getMinimumSize() {
143                        return getPreferredSize();
144                }
145
146                @Override
147                public Dimension getMaximumSize() {
148                        return getPreferredSize();
149                }
150
151                @Override
152                public Dimension getPreferredSize() {
153                        return new Dimension(135,80);
154                }
155
156
157                @Override
158                public void paint(Graphics g) {
159
160                        if (big == null) {
161                                return;
162                        }
163
164                        big.setBackground(getBackground());
165                        big.clearRect(0,0,w,h);
166
167                        float freeMemory = r.freeMemory();
168                        float totalMemory = r.totalMemory();
169
170                        // .. Draw allocated and used strings ..
171                        big.setColor(Color.green);
172                        big.drawString(String.valueOf((int) totalMemory/1024) + "K allocated",  4.0f, ascent+0.5f);
173                        usedStr = String.valueOf(((int) (totalMemory - freeMemory))/1024)
174                                        + "K used";
175                        big.drawString(usedStr, 4, h-descent);
176
177                        // Calculate remaining size
178                        float ssH = ascent + descent;
179                        float remainingHeight = h - (ssH*2) - 0.5f;
180                        float blockHeight = remainingHeight/10;
181                        float blockWidth = 20.0f;
182                        //float remainingWidth = (float) (w - blockWidth - 10);
183
184                        // .. Memory Free ..
185                        big.setColor(mfColor);
186                        int MemUsage = (int) ((freeMemory / totalMemory) * 10);
187                        int i = 0;
188                        for ( ; i < MemUsage ; i++) {
189                                mfRect.setRect(5,ssH+i*blockHeight,
190                                                blockWidth,blockHeight-1);
191                                big.fill(mfRect);
192                        }
193
194                        // .. Memory Used ..
195                        big.setColor(Color.green);
196                        for ( ; i < 10; i++)  {
197                                muRect.setRect(5,ssH+i*blockHeight,
198                                                blockWidth,blockHeight-1);
199                                big.fill(muRect);
200                        }
201
202                        // .. Draw History Graph ..
203                        big.setColor(graphColor);
204                        int graphX = 30;
205                        int graphY = (int) ssH;
206                        int graphW = w - graphX - 5;
207                        int graphH = (int) remainingHeight;
208                        graphOutlineRect.setRect(graphX, graphY, graphW, graphH);
209                        big.draw(graphOutlineRect);
210
211                        int graphRow = graphH/10;
212
213                        // .. Draw row ..
214                        for (int j = graphY; j <= graphH+graphY; j += graphRow) {
215                                graphLine.setLine(graphX,j,graphX+graphW,j);
216                                big.draw(graphLine);
217                        }
218
219                        // .. Draw animated column movement ..
220                        int graphColumn = graphW/15;
221
222                        if (columnInc == 0) {
223                                columnInc = graphColumn;
224                        }
225
226                        for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {
227                                graphLine.setLine(j,graphY,j,graphY+graphH);
228                                big.draw(graphLine);
229                        }
230
231                        --columnInc;
232
233                        if (pts == null) {
234                                pts = new int[graphW];
235                                ptNum = 0;
236                        } else if (pts.length != graphW) {
237                                int[] tmp = null;
238                                if (ptNum < graphW) {
239                                        tmp = new int[ptNum];
240                                        System.arraycopy(pts, 0, tmp, 0, tmp.length);
241                                } else {
242                                        tmp = new int[graphW];
243                                        System.arraycopy(pts, pts.length-tmp.length, tmp, 0, tmp.length);
244                                        ptNum = tmp.length - 2;
245                                }
246                                pts = new int[graphW];
247                                System.arraycopy(tmp, 0, pts, 0, tmp.length);
248                        } else {
249                                big.setColor(Color.yellow);
250                                pts[ptNum] = (int)(graphY+graphH*(freeMemory/totalMemory));
251                                for (int j=graphX+graphW-ptNum, k=0;k < ptNum; k++, j++) {
252                                        if (k != 0) {
253                                                if (pts[k] != pts[k-1]) {
254                                                        big.drawLine(j-1, pts[k-1], j, pts[k]);
255                                                } else {
256                                                        big.fillRect(j, pts[k], 1, 1);
257                                                }
258                                        }
259                                }
260                                if (ptNum+2 == pts.length) {
261                                        // throw out oldest point
262                                        for (int j = 1;j < ptNum; j++) {
263                                                pts[j-1] = pts[j];
264                                        }
265                                        --ptNum;
266                                } else {
267                                        ptNum++;
268                                }
269                        }
270                        g.drawImage(bimg, 0, 0, this);
271                }
272
273
274                public void start() {
275                        thread = new Thread(this);
276                        thread.setPriority(Thread.MIN_PRIORITY);
277                        thread.setName("MemoryMonitor");
278                        thread.start();
279                }
280
281
282                public synchronized void stop() {
283                        thread = null;
284                        notify();
285                }
286
287
288                @Override
289                public void run() {
290
291                        Thread me = Thread.currentThread();
292
293                        while (thread == me && !isShowing() || getSize().width == 0) {
294                                try {
295                                        Thread.sleep(500);
296                                } catch (InterruptedException e) { return; }
297                        }
298
299                        while (thread == me && isShowing()) {
300                                Dimension d = getSize();
301                                if (d.width != w || d.height != h) {
302                                        w = d.width;
303                                        h = d.height;
304                                        bimg = (BufferedImage) createImage(w, h);
305                                        big = bimg.createGraphics();
306                                        big.setFont(font);
307                                        FontMetrics fm = big.getFontMetrics(font);
308                                        ascent = fm.getAscent();
309                                        descent = fm.getDescent();
310                                }
311                                repaint();
312                                try {
313                                        Thread.sleep(sleepAmount);
314                                } catch (InterruptedException e) { break; }
315                                if (MemoryMonitor.dateStampCB.isSelected()) {
316                                        System.out.println(new Date().toString() + " " + usedStr);
317                                }
318                        }
319                        thread = null;
320                }
321        }
322
323
324        public static void main(String[] s) {
325                final MemoryMonitor demo = new MemoryMonitor();
326                WindowListener l = new WindowAdapter() {
327                        @Override
328                        public void windowClosing(WindowEvent e) {System.exit(0);}
329                        @Override
330                        public void windowDeiconified(WindowEvent e) { demo.surf.start(); }
331                        @Override
332                        public void windowIconified(WindowEvent e) { demo.surf.stop(); }
333                };
334                JFrame f = new JFrame("Java2D Demo - MemoryMonitor");
335                f.addWindowListener(l);
336                f.getContentPane().add("Center", demo);
337                f.pack();
338                f.setSize(new Dimension(200,200));
339                f.setVisible(true);
340                demo.surf.start();
341        }
342}