Package net.cakenet.jsaton.ui.tools

Source Code of net.cakenet.jsaton.ui.tools.MemoryUsageWindow

package net.cakenet.jsaton.ui.tools;

import net.cakenet.jsaton.util.ImageUtil;
import net.cakenet.jsaton.util.TimeUtil;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.SortedMap;
import java.util.TreeMap;

public class MemoryUsageWindow extends ToolWindow {
    private static final int[] values = new int[]{10, 25, 50, 100, 250, 500, 1000, 1500, 2000, 3000, 4000, 5000};
    private static final int HISTORY_LEN = 2048;

    private JPanel panel1;
    private JProgressBar usagePercentage;
    private JButton gc;
    private JLabel graph;
    private JSpinner intervalSelect;
    private BufferedImage buffer;
    private TreeMap<Long, Long> history = new TreeMap<>();
    private transient int interval = 500;

    public MemoryUsageWindow() {
        super("Memory usage");

        gc.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new Thread() {
                    public void run() {
                        Runtime.getRuntime().gc();
                    }
                }.start();
            }
        });
        Thread t = new Thread() {
            public void run() {
                while (true) {
                    updateUsage();
                    try {
                        Thread.sleep(interval);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        graph.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                long curTime = System.currentTimeMillis();
                int w = getWidth();
                int idx = (w - e.getX());
                long timeGuest = curTime - (interval * idx);
                Long key = history.floorKey(timeGuest);
                if (key == null)
                    graph.setToolTipText(null);
                else {
                    graph.setToolTipText(String.format("%dMB about %s ago", history.get(key) / 1048576L,
                            TimeUtil.timeString((int) (curTime - key))));
                }
            }
        });
        t.setDaemon(true);
        t.setPriority(1);
        t.start();
        intervalSelect.setEditor(new JSpinner.NumberEditor(intervalSelect));
        intervalSelect.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                interval = (Integer) intervalSelect.getValue();
                updateUsage();
            }
        });
    }

    private void updateUsage() {
        long curTime = System.currentTimeMillis();
        Runtime r = Runtime.getRuntime();
        long total = r.totalMemory();
        long free = r.freeMemory();
        long used = total - free;
        history.put(curTime, used);
        if (history.size() > HISTORY_LEN)
            history.pollFirstEntry();

        // Draw...

        // Find maximum in history...
        if (!isVisible())
            return;
        Dimension size = graph.getSize();
        if (size.width <= 0 || size.height <= 0)
            return;
        if (buffer == null || buffer.getWidth() != size.width || buffer.getHeight() != size.height) {
            buffer = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
            graph.setIcon(new ImageIcon(buffer));
        }

        // do it....
        final long time_min = curTime - (interval * size.width);
        Graphics g = buffer.getGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, size.width, size.height);

        // Todo: draw grid...
        final int[] graph_intervales = new int[]{500, 1000, 5000, 10000, 20000};
        final int mem_megs = (int) (total / 1048576L);
        int mem_interval = ((mem_megs - (mem_megs % 25)) / 25);
        if (mem_interval == 0)
            mem_interval = ((mem_megs - (mem_megs % 10)) / 10);
        final Color graphColor = Color.BLUE;
        Color intervalColor = graphColor.darker().darker();
        final int min_int_width = 20;
        int height = size.height / mem_interval;
        g.setColor(intervalColor);
        for (int y = 0; y < size.height; y += height)
            g.drawLine(0, y, size.width, y);
        for (int i = graph_intervales.length - 1; i >= 0; i--) {
            int ival = graph_intervales[i];
            float width = ((float) ival / (float) interval);
            if (width < min_int_width)
                continue;
            g.setColor(intervalColor);
            for (float x = size.width; x >= 0; x -= width)
                g.drawLine((int) x, 0, (int) x, size.height);

            intervalColor = intervalColor.darker().darker();
        }


        g.setColor(graphColor);
        Long start = history.floorKey(time_min);
        if (start == null)
            start = history.ceilingKey(time_min);

        SortedMap<Long, Long> interest = history.tailMap(start);
        int prevY = -1;
        int prevX = -1;
        for (SortedMap.Entry<Long, Long> e : interest.entrySet()) {
            long u = e.getValue();
            long t = e.getKey();
            int xOffset = (int) (curTime - t) / this.interval;
            float perc = (((float) u) / ((float) total));
            int y = size.height - (int) (perc * size.height);
            int x = size.width - xOffset;
            if (prevY != -1)
                g.drawLine(prevX, prevY, x, y);
            prevY = y;
            prevX = x;
        }

        usagePercentage.setValue((int) ((((float) used) / ((float) total)) * 100));
        usagePercentage.setString(String.format("%dMB of %dMB", used / 1048576L, total / 1048576L));
        redraw();
    }

    private void redraw() {
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    redraw();
                }
            });
            return;
        }

        usagePercentage.repaint();
        graph.repaint();
    }

    public Icon getIcon() {
        return ImageUtil.loadIcon("icons/chart_line.png");
    }

    public Component getContents() {
        return panel1;
    }

    private void createUIComponents() {
        intervalSelect = new JSpinner(new SpinnerNumberModel() {
            private java.util.List<ChangeListener> listeners = new LinkedList<>();

            private int current = 500;

            public Object getValue() {
                return current;
            }

            public void setValue(Object value) {
                this.current = (Integer) value;
                if (listeners.isEmpty())
                    return;
                ChangeEvent ce = new ChangeEvent(this);
                for (ChangeListener l : listeners.toArray(new ChangeListener[listeners.size()]))
                    l.stateChanged(ce);
            }

            private int nearestIndex() {
                for (int i = 0; i < values.length; i++) {
                    if (values[i] > current) {
                        int idx = i - 1;
                        if (idx < 0)
                            return 0;
                        return idx;
                    }
                }
                return values.length - 1;
            }

            public Object getNextValue() {
                int idx = nearestIndex() + 1;
                if (idx >= values.length)
                    return null;
                return values[idx];
            }

            public Object getPreviousValue() {
                int idx = nearestIndex() - 1;
                if (idx < 0)
                    return null;
                return values[idx];
            }

            public void addChangeListener(ChangeListener l) {
                listeners.add(l);
            }

            public void removeChangeListener(ChangeListener l) {
                listeners.remove(l);
            }
        });
    }
}
TOP

Related Classes of net.cakenet.jsaton.ui.tools.MemoryUsageWindow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.