import java.awt.GridLayout;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.io.IOException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import javax.management.MBeanServerConnection;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

public class HeapChartIndicator extends JPanel {
    private JLabel usedValue;
    
    private MemoryMXBean memorymxbean;
    private DefaultPieDataset data;

    public HeapChartIndicator() {
        data = new DefaultPieDataset();
        data.setValue("Used", 0.0);
        data.setValue("Committed", 0.0);
        data.setValue("Not Used", 0.0);

        JFreeChart chart = ChartFactory.createPieChart3D(
            "Heap Usage",
            data,
            true,
            true,
            false
        );

        ChartPanel panel = new ChartPanel(chart);
 
        add(panel);
    }

    public void setMBeanServerConnection(MBeanServerConnection connection) {
        try {
            memorymxbean = ManagementFactory.newPlatformMXBeanProxy(
                connection,
                ManagementFactory.MEMORY_MXBEAN_NAME,
                MemoryMXBean.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private MemoryUsage getHeapUsage() {
        return memorymxbean.getHeapMemoryUsage();
    }

    class Worker extends SwingWorker<MemoryUsage,Object> {
        @Override
        public MemoryUsage doInBackground() {
            return getHeapUsage();
        }
                                                                                
        @Override
        protected void done() {
            try {
                // doInBackgroundで取得したMemoryUsageを取得
                MemoryUsage usage = get();

                double used = usage.getUsed();
                double committed = usage.getCommitted();
                double max = usage.getMax();

                data.setValue("Used", used);
                data.setValue("Committed", committed - used);
                data.setValue("Not Used", max - committed);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } catch (ExecutionException ex) {
                ex.printStackTrace();
            }
        }
    }

    public SwingWorker<?,?> newSwingWorker() {
        return new Worker();
    }
}
