view analyzer/src/jp/co/ntt/oss/heapstats/gui/GUIMain.java @ 53:bfc42ff08b48 1.1.4

Bump to 1.1.4 Review-thread: http://icedtea.classpath.org/pipermail/heapstats/2016-April/001546.html
author KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
date Thu, 28 Apr 2016 12:47:11 +0900
parents e6d8b7111e5c
children 276d14d7b511
line wrap: on
line source

/*
 * GUIMain.java
 * Created on 2011/09/07
 *
 * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

package jp.co.ntt.oss.heapstats.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

import jp.co.ntt.oss.heapstats.csv.CSVDumper;
import jp.co.ntt.oss.heapstats.gui.snapshot.ParserEventHandlerImpl;
import jp.co.ntt.oss.heapstats.gui.snapshot.SnapShotReader;
import jp.co.ntt.oss.heapstats.parser.HeapStatsParser;

import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.entity.CategoryItemEntity;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.plot.CategoryMarker;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.ui.Layer;

/**
 * extends {@link JFrame}<br>
 * implements {@link ActionListener}<br>
 * <br>
 * Draw the main part of HeapStats.
 */
public class GUIMain extends JFrame implements
                                   ActionListener,
                                   ChartMouseListener {
    /** serialVersionUID. */
    private static final long serialVersionUID = -6668360652023124873L;

    /** The file name of the icon image. */
    private static final String HEAPSTATS_ICON = "heapstats-icon.png";

    /** The file name of the logo image. */
    private static final String HEAPSTATS_LOGO = "heapstats-logo.png";

    /** the alpha transparency (must be in the range 0.0f to 1.0f). */
    private static final float ALPHA_TRANSPARENCY = 0.7f;

    /** Menu-File-Log File Open. */
    private JMenuItem logOpen;

    /** Menu-File-Open. */
    private JMenuItem fileOpen;

    /** Menu-File-Exit. */
    private JMenuItem fileExitBtn;

    /** Menu-Option-Tab Bar Display. */
    private JCheckBoxMenuItem tabbedBar;

    /** Menu-Option-RankLevel. */
    private JMenuItem optionRankLevelBtn;

    /** Menu-Option-CSV-Heap-All. */
    private JMenuItem csvHeapAll;

    /** Menu-Option-CSV-Heap-Selected. */
    private JMenuItem csvHeapSelected;

    /** Menu-Option-CSV-Statistics-All. */
    private JMenuItem csvGcAll;

    /** Menu-Option-CSV-Statistics-Selected. */
    private JMenuItem csvGcSelected;

    /** Menu-Help-Help HeapStats. */
    private JMenuItem helpHeapStats;

    /** Menu-Help-About HeapStats. */
    private JMenuItem aboutHeapStats;

    /** Main Data Tab. */
    private JTabbedPane mainTab;

    /** Select Data Button. */
    private JButton chooserBtn;

    /** Dump File Names. */
    private JTextField fileName;

    /** Select Range StartDate. */
    private JComboBox startCombo;

    /** Select Range EndDate. */
    private JComboBox endCombo;

    /** Select Range OK Button. */
    private JButton okButton;

    /** SnapShot Tab. */
    private JTabbedPane snapshotTabbed;

    /** Delta Data. */
    private DiffDialog deltaDlg;

    /** SnapShot Data. */
    private SnapShotDialog ssDlg;

    /** SnapShot Main Component. */
    private Box snapComp;

    /** Delta Main Component. */
    private JSplitPane deltaComp;

    /** Summary Data. */
    private GCDialog gcDlg;

    /** Summary Main Component. */
    private Box gcComp;

    /**
     * Offsets Key is Date. Data is the absolute path of the snapshot directory
     * after unzip.
     */
    private Map<Date, String> offsets;

    /** Object to a CSV GC heap usage statistics. */
    private CSVDumper dumper;

    /** ResourceDialog Data. */
    private ResourceDialog resourceDlg;

    /** Resource Main Component. */
    private Box rsrcComp;

    /** Log file reading screen part. */
    private SelectLogfiles selectLogPanel;

    /** LogDetail Data. */
    private LogDetailDialog logDlg;

    /** LogDetail Main Component. */
    private JSplitPane logComp;

    /** Log Collect Tab. */
    private JTabbedPane logTabbar;

    /** Reference Data Tab. */
    private ReferenceDialog refDlg;

    /** Reference Data Component. */
    private JPanel refComp;

    /**
     * Creates a new, initially invisible Frame with the specified title.
     *
     * @param title the title for the frame
     */
    public GUIMain(final String title) {
        super(title);

        try {
            GuiCommon.load();
        } catch (Throwable e) {
            // Messages are displayed in the Launcher class.
            e.printStackTrace();
        }

        URL url = getClass().getClassLoader().getResource(HEAPSTATS_ICON);
        setIconImage(Toolkit.getDefaultToolkit().createImage(url));

        ssDlg = null;
        deltaDlg = null;
        gcDlg = null;
        resourceDlg = null;
        logDlg = null;
        refDlg = null;

        offsets = new TreeMap<Date, String>();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(GuiCommon.DEFAULT_FRAME_WIDTH, GuiCommon.DEFAULT_FRAME_HEIGHT);

        JComponent.setDefaultLocale(new Locale(GuiCommon.getLanguage()));

        createMenuBar();
        addComponent();
        setLocationByPlatform(true);
    }

    /**
     * Creates the Menu bar.
     */
    private void createMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        // Menu-File
        JMenu menuFile = new JMenu(GuiCommon.getResources().getString(
                GuiCommon.MENU_FILE));
        menuFile.setMnemonic(KeyEvent.VK_F);

        logOpen = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_FILE_LOGOPEN), KeyEvent.VK_L);
        fileOpen = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_FILE_OPEN), KeyEvent.VK_S);
        fileOpen.addActionListener(this);
        fileExitBtn = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_FILE_EXIT), KeyEvent.VK_E);
        fileExitBtn.addActionListener(this);

        menuFile.add(logOpen);
        menuFile.add(fileOpen);
        menuFile.add(fileExitBtn);

        // Menu-Option
        JMenu menuOption = new JMenu(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION));
        menuOption.setMnemonic(KeyEvent.VK_O);

        // Menu-Option-Tab Bar Display
        tabbedBar = new JCheckBoxMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_TAB), true);
        tabbedBar.setMnemonic(KeyEvent.VK_T);
        tabbedBar.addActionListener(this);
        menuOption.add(tabbedBar);

        // Menu-Option-RankLevel
        optionRankLevelBtn = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_RANKLEVEL), KeyEvent.VK_R);
        optionRankLevelBtn.addActionListener(this);
        menuOption.add(optionRankLevelBtn);

        // Menu-Option-CSV
        JMenu csvMenu = new JMenu(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSV));
        csvMenu.setMnemonic(KeyEvent.VK_C);

        JMenu csvHeap = new JMenu(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSVHEAP));
        csvHeap.setMnemonic(KeyEvent.VK_H);
        JMenu csvGc = new JMenu(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSVGC));
        csvGc.setMnemonic(KeyEvent.VK_G);

        csvMenu.add(csvHeap);
        csvMenu.add(csvGc);

        // Menu-Option-CSV-All
        csvHeapAll = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSVALL), KeyEvent.VK_A);
        csvHeapAll.addActionListener(this);
        csvHeap.add(csvHeapAll);

        // Menu-Option-CSV-Selected
        csvHeapSelected = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSVSELECTED), KeyEvent.VK_S);
        csvHeapSelected.addActionListener(this);
        csvHeap.add(csvHeapSelected);

        // Menu-Option-CSV-All
        csvGcAll = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSVALL), KeyEvent.VK_A);
        csvGcAll.addActionListener(this);
        csvGc.add(csvGcAll);

        // Menu-Option-CSV-Selected
        csvGcSelected = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_OPTION_CSVSELECTED), KeyEvent.VK_S);
        csvGcSelected.addActionListener(this);
        csvGc.add(csvGcSelected);

        menuOption.add(csvMenu);

        // Menu-Help
        JMenu menuHelp = new JMenu(GuiCommon.getResources().getString(
                GuiCommon.MENU_HELP));
        menuHelp.setMnemonic(KeyEvent.VK_H);

        helpHeapStats = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_USE), KeyEvent.VK_H);
        helpHeapStats.addActionListener(this);

        // Menu-Help-About HeapStats
        aboutHeapStats = new JMenuItem(GuiCommon.getResources().getString(
                GuiCommon.MENU_HELP_VERSION), KeyEvent.VK_A);
        aboutHeapStats.addActionListener(this);

        menuHelp.add(helpHeapStats);
        menuHelp.add(aboutHeapStats);

        menuBar.add(menuFile);
        menuBar.add(menuOption);
        menuBar.add(menuHelp);

        setJMenuBar(menuBar);
    }

    /**
     * Add the component to the screen.
     */
    private void addComponent() {
        mainTab = new JTabbedPane();
        add(mainTab);

        startDraw(-1, -1);

        mainTab.add(
                GuiCommon.getResources().getString(
                        GuiCommon.MAIN_TAB_LOGCOLLECT), addLogCollect());
        mainTab.add(
                GuiCommon.getResources().getString(GuiCommon.MAIN_TAB_SNAPSHOT),
                addSnapShot());
    }

    /**
     * Add the components to the screen snapshot.
     *
     * @return the snapshot reading screen.
     */
    private Component addSnapShot() {
        Box box = Box.createVerticalBox();
        box.setBorder(BorderFactory.createEmptyBorder(GuiCommon.BORDER_SIZE,
                GuiCommon.BORDER_SIZE, GuiCommon.BORDER_SIZE,
                GuiCommon.BORDER_SIZE));
        box.add(Box.createVerticalStrut(GuiCommon.BORDER_SIZE));

        // FILE Select Main Part
        ExpansionContractionPanel exPanel = new ExpansionContractionPanel(
                GuiCommon.getResources().getString(GuiCommon.TITLE_MAIN));

        JPanel panelMain = new JPanel();
        panelMain.setLayout(new BorderLayout(GuiCommon.BORDER_SIZE,
                GuiCommon.BORDER_SIZE));
        panelMain.setBackground(Color.WHITE);

        chooserBtn = new JButton(GuiCommon.getResources().getString(
                GuiCommon.SELECT_DATA));
        chooserBtn.addActionListener(this);

        // SELECT FILE
        JPanel panelFile = new JPanel();
        panelFile.setLayout(new BorderLayout(GuiCommon.BORDER_SIZE,
                GuiCommon.BORDER_SIZE));
        panelFile.setBackground(Color.WHITE);

        fileName = new JTextField();

        panelFile.add(chooserBtn, BorderLayout.WEST);
        panelFile.add(fileName, BorderLayout.CENTER);
        panelMain.add(panelFile, BorderLayout.NORTH);

        // Select Range
        JPanel panelRange = new JPanel();
        okButton = new JButton("OK");
        okButton.addActionListener(this);
        panelRange.setLayout(new BoxLayout(panelRange, BoxLayout.X_AXIS));
        panelRange.setBackground(Color.WHITE);

        startCombo = new JComboBox();
        startCombo.setEditable(true);

        JLabel llabel = new JLabel(" ~ ");
        endCombo = new JComboBox();
        endCombo.setEditable(true);

        panelRange.add(new JLabel(GuiCommon.getResources().getString(
                GuiCommon.SELECT_RANGE)
                + " "));
        panelRange.add(startCombo);
        panelRange.add(llabel);
        panelRange.add(endCombo);
        panelRange.add(Box.createVerticalStrut(GuiCommon.BORDER_SIZE));
        panelRange.add(okButton);

        panelMain.add(panelRange, BorderLayout.CENTER);
        panelRange.setLayout(new BoxLayout(panelRange, BoxLayout.X_AXIS));

        // Filter
        exPanel.setComponent(panelMain, true);

        box.add(exPanel);

        //
        box.add(Box.createVerticalStrut(GuiCommon.BORDER_SIZE));
        snapshotTabbed = new JTabbedPane();

        box.add(snapshotTabbed);
        box.revalidate();

        JPanel imgPane = new JPanel();
        imgPane.setBackground(Color.WHITE);
        snapshotTabbed
                .add(GuiCommon.getResources().getString(
                        GuiCommon.TAB_TITLE_SUMMARY), gcDlg.getComp());
        snapshotTabbed.add(
                GuiCommon.getResources().getString(GuiCommon.TAB_TITLE_DELA),
                deltaDlg.getComp());
        snapshotTabbed.add(
                GuiCommon.getResources()
                        .getString(GuiCommon.TAB_TITLE_SNAPSHOT), ssDlg
                        .getComp());
        snapshotTabbed.add(
                GuiCommon.getResources().getString(
                        GuiCommon.TAB_TITLE_REFERENCE), refDlg.getComp());

        return box;
    }

    /**
     * Add the components to the screen LogCollect.
     *
     * @return Collection component of the log screen
     */
    private Component addLogCollect() {
        Box box = Box.createVerticalBox();
        box.setBorder(BorderFactory.createEmptyBorder(GuiCommon.BORDER_SIZE,
                GuiCommon.BORDER_SIZE, GuiCommon.BORDER_SIZE,
                GuiCommon.BORDER_SIZE));
        box.add(Box.createVerticalStrut(GuiCommon.BORDER_SIZE));

        // FILE Select Main Part
        selectLogPanel = new SelectLogfiles(GuiCommon.getResources().getString(
                GuiCommon.TITLE_LOG), resourceDlg);

        logOpen.addActionListener(this);

        box.add(selectLogPanel);
        box.add(Box.createVerticalStrut(GuiCommon.BORDER_SIZE));

        logTabbar = new JTabbedPane();

        box.add(logTabbar);
        box.revalidate();

        logTabbar.add(
                GuiCommon.getResources().getString(GuiCommon.TAB_RESOURCE_SUMMARY),
                rsrcComp);
        logTabbar.add(
                GuiCommon.getResources().getString(GuiCommon.TAB_LOG_DETAIL),
                logComp);

        return box;
    }

    /**
     * Draw a snapshot.
     *
     * @param start Start time of the snapshot for drawing
     * @param end End time of the snapshot for drawing
     */
    private void startDraw(final int start, final int end) {
        List<SnapShotReader> diffOffsets = new ArrayList<SnapShotReader>();

        int i = 0;
        for (Map.Entry<Date, String> entry : offsets.entrySet()) {
            if (i >= start && i <= end) {
                diffOffsets.add(new SnapShotReader(entry.getValue()));
            }
            i++;
        }

        if (gcDlg == null || deltaDlg == null || ssDlg == null
                || refDlg == null) {
            gcDlg = new GCDialog(this);
            refDlg = new ReferenceDialog(this);
            ssDlg = new SnapShotDialog(this, refDlg);
            deltaDlg = new DiffDialog(this, ssDlg, refDlg);
            logDlg = new LogDetailDialog(this);
            resourceDlg = new ResourceDialog(this, logDlg);

            gcComp = gcDlg.getComp();
            deltaComp = deltaDlg.getComp();
            snapComp = ssDlg.getComp();
            refComp = refDlg.getComp();
            rsrcComp = resourceDlg.getComp();
            logComp = logDlg.getComp();
        } else {
            // Summary Data
            gcDlg.draw(diffOffsets);

            // Delta Data
            try {
                deltaDlg.draw(diffOffsets, true);
            } catch (Exception e) {
                e.printStackTrace();
                GuiCommon.showMessage(this, GuiCommon.BASEE13,
                        JOptionPane.ERROR_MESSAGE);
            }

            // SnapShot Data
            try {
                ssDlg.draw(diffOffsets.get(0), null, null);
            } catch (Exception e) {
                GuiCommon.showMessage(this, GuiCommon.BASEE12,
                        JOptionPane.ERROR_MESSAGE);
            }

            refDlg.clear();
        }
    }

    @Override
    public final void actionPerformed(final ActionEvent actionevent) {
        Object eventSource = actionevent.getSource();

        try {
            if (!deltaDlg.isDone() || (dumper != null && !dumper.isDone())) {
                // Being processed
                GuiCommon.showMessage(this, GuiCommon.BASEW02,
                        JOptionPane.WARNING_MESSAGE);
                return;
            }

            if (eventSource.equals(chooserBtn) || eventSource.equals(fileOpen)) {
                // SELECT DATA
                JFileChooser fileDlg = new JFileChooser();
                fileDlg.setCurrentDirectory(GuiCommon.getCurrentDir());
                fileDlg.setMultiSelectionEnabled(true);
                int result = fileDlg.showOpenDialog(this);

                if (result == JFileChooser.APPROVE_OPTION) {
                    try {
                        GuiCommon.setCurrentDir(fileDlg.getCurrentDirectory());
                    } catch (IOException e) {
                        GuiCommon.showMessage(this, GuiCommon.BASEE17,
                                JOptionPane.ERROR_MESSAGE);
                    }

                    // Clear information about each dialog.
                    ssDlg.clear();
                    deltaDlg.clear();
                    gcDlg.clear();
                    refDlg.clear();
                    startCombo.removeAllItems();
                    endCombo.removeAllItems();
                    fileName.setText("");

                    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                    if (loadJavaHeapInfoFile(fileDlg)) {
                        setSelectData();
                    }

                    if (eventSource.equals(fileOpen)) {
                        mainTab.setSelectedIndex(1);
                    }
                }
            } else if (eventSource.equals(helpHeapStats)) {
                // How to use
                popupManual();
            } else if (eventSource.equals(aboutHeapStats)) {
                // Version Dialog
                StringBuilder buf = new StringBuilder();
                buf.append("\n\n  Version: 1.1.4\n\n");
                buf.append("HeapStats is licensed under the GNU General Public License version 2.\n\n");
                buf.append("about:license\n");
                buf.append("  JFreeChart  :  the GNU Lesser ");
                buf.append("General Public License\n");
                buf.append("  JGraphX     :  the Berkeley Software ");
                buf.append("Distribution License\n\n");
                buf.append("  Copyright (C) 2011-2016 Nippon Telegraph and ");
                buf.append("Telephone Corporation\n\n");

                JLabel title = new JLabel("  HeapStats Analyzer\n\n\n");
                title.setFont(new Font(Font.DIALOG, Font.BOLD, 20));

                Object[] info = new Object[2];
                info[0] = title;
                info[1] = buf.toString();
                JOptionPane
                        .showMessageDialog(this, info, GuiCommon.getResources()
                                .getString(GuiCommon.VERSION_DIALOG_TITLE),
                                JOptionPane.PLAIN_MESSAGE, new ImageIcon(
                                        getClass().getClassLoader()
                                                .getResource(HEAPSTATS_LOGO)));
            } else if (eventSource.equals(fileExitBtn)) {
                // Exit
                clearOffsets();
                Runtime.getRuntime().exit(0);
            } else if (eventSource.equals(optionRankLevelBtn)) {
                setRankLevel();
            } else if (eventSource.equals(csvHeapAll)) {
                // Java Heap CSV
                dumpCsv(true, true);
            } else if (eventSource.equals(csvHeapSelected)) {
                // Java Heap CSV
                dumpCsv(true, false);
            } else if (eventSource.equals(csvGcAll)) {
                // Java GC statistics CSV
                dumpCsv(false, true);
            } else if (eventSource.equals(csvGcSelected)) {
                // Java GC statistics CSV
                dumpCsv(false, false);
            } else if (eventSource.equals(okButton)) {
                // Draws the Summary, Delta and SnapShot.
                int start = startCombo.getSelectedIndex();
                int end = endCombo.getSelectedIndex();

                if (selectRange(start, end)) {
                    startDraw(start, end);
                }
            } else if (eventSource.equals(tabbedBar)) {
                // Delte Data
                popupDialog();
            } else if (eventSource.equals(logOpen)) {
                mainTab.setSelectedIndex(0);
                selectLogPanel.actionPerformed(actionevent);
            } else {
                deltaDlg.actionPerformed(actionevent);
            }
        } catch (IOException e) {
            GuiCommon.showMessage(this, GuiCommon.BASEE16,
                    JOptionPane.ERROR_MESSAGE);
        } catch (Throwable e) {
            GuiCommon.showMessage(this, GuiCommon.BASEE16,
                    JOptionPane.ERROR_MESSAGE);
        } finally {
            setCursor(Cursor.getDefaultCursor());
        }
    }

    @Override
    public final void chartMouseClicked(final ChartMouseEvent arg0) {
        if (!deltaDlg.isDone()) {
            return;
        }

        ChartEntity entry = arg0.getEntity();
        if (entry instanceof CategoryItemEntity) {

            SnapShotReader reader = deltaDlg.getOffsets().get(
                    ((CategoryItemEntity) entry).getColumnKey());

            CategoryPlot plot = deltaDlg.getUsageChart().getChart()
                    .getCategoryPlot();
            plot.clearDomainMarkers();
            CategoryMarker marker = new CategoryMarker(
                    ((CategoryItemEntity) entry).getColumnKey());
            marker.setPaint(Color.WHITE);
            marker.setAlpha(ALPHA_TRANSPARENCY);
            plot.addDomainMarker(marker, Layer.FOREGROUND);

            plot = deltaDlg.getRankChart().getChart().getCategoryPlot();
            plot.clearDomainMarkers();
            plot.addDomainMarker(marker, Layer.FOREGROUND);

            plot = gcDlg.getGcPanel().getChart().getCategoryPlot();
            plot.clearDomainMarkers();
            plot.addDomainMarker(marker, Layer.FOREGROUND);

            try {
                ssDlg.draw(reader, deltaDlg.getSearchClass(),
                        deltaDlg.getFilterList());
            } catch (IOException e) {
                GuiCommon.showMessage(this, GuiCommon.BASEE12,
                        JOptionPane.ERROR_MESSAGE);
            } catch (ClassNotFoundException e) {
                GuiCommon.showMessage(this, GuiCommon.BASEE12,
                        JOptionPane.ERROR_MESSAGE);
            }

            refDlg.clear();
        }
    }

    @Override
    public void chartMouseMoved(final ChartMouseEvent chartmouseevent) {
    }

    /**
     * Check the start and end snapshot of the selection period.
     *
     * @param start Start time of the snapshot for drawing
     * @param end End time of the snapshot for drawing
     * @return Return the check result.
     */
    private boolean selectRange(final int start, final int end) {
        if (start == -1 || end == -1) {
            GuiCommon.showMessage(this, GuiCommon.BASEE05,
                    JOptionPane.ERROR_MESSAGE);
            return false;
        } else if (start > end) {
            // Reversed start and end
            GuiCommon.showMessage(this, GuiCommon.BASEE06,
                    JOptionPane.ERROR_MESSAGE);
            return false;
        } else if (start == end) {
            // Match the start and end
            GuiCommon.showMessage(this, GuiCommon.BASEE07,
                    JOptionPane.ERROR_MESSAGE);
            return false;
        }

        if (startCombo.getSelectedItem().toString()
                .equals(endCombo.getSelectedItem().toString())) {
            // Match the start and end
            GuiCommon.showMessage(this, GuiCommon.BASEE07,
                    JOptionPane.ERROR_MESSAGE);
            return false;
        }
        return true;
    }

    /**
     * Draw tab to obtain a snapshot statistics for selected period.
     */
    private void popupDialog() {
        if (tabbedBar.isSelected()) {
            if (!snapshotTabbed.isVisible()) {
                gcDlg.setVisible(false);
                deltaDlg.setVisible(false);
                ssDlg.setVisible(false);
                refDlg.setVisible(false);
                resourceDlg.setVisible(false);
                logDlg.setVisible(false);

                snapshotTabbed.add(
                        GuiCommon.getResources().getString(
                                GuiCommon.TAB_TITLE_SUMMARY), gcComp);
                snapshotTabbed.add(
                        GuiCommon.getResources().getString(
                                GuiCommon.TAB_TITLE_DELA), deltaComp);
                snapshotTabbed.add(
                        GuiCommon.getResources().getString(
                                GuiCommon.TAB_TITLE_SNAPSHOT), snapComp);
                snapshotTabbed.add(
                        GuiCommon.getResources().getString(
                                GuiCommon.TAB_TITLE_REFERENCE), refComp);

                logTabbar.add(
                        GuiCommon.getResources().getString(
                                GuiCommon.TAB_TITLE_RESOUCE), rsrcComp);
                logTabbar.add(
                        GuiCommon.getResources().getString(
                                GuiCommon.TAB_TITLE_LOG), logComp);

                snapshotTabbed.setVisible(true);
                logTabbar.setVisible(true);

                setSize(getSize().width, GuiCommon.DEFAULT_FRAME_HEIGHT);
            }
        } else {
            if (snapshotTabbed.isVisible()) {
                snapshotTabbed.setVisible(false);
                logTabbar.setVisible(false);

                gcDlg.setComp(gcComp);
                gcDlg.setVisible(true);

                deltaDlg.setComp(deltaComp);
                deltaDlg.setVisible(true);

                ssDlg.setComp(snapComp);
                ssDlg.setVisible(true);

                refDlg.setComp(refComp);
                refDlg.setVisible(true);

                resourceDlg.setComp(rsrcComp);
                resourceDlg.setVisible(true);

                logDlg.setComp(logComp);
                logDlg.setVisible(true);

                setSize(getSize().width, 190);
            }
        }
    }

    /**
     * Java heap to load the file information output by the agent.
     *
     * @param fileDlg Files output by the agent
     * @return Return the result.true is success.
     */
    private boolean loadJavaHeapInfoFile(final JFileChooser fileDlg) {
        try {
            clearOffsets();

            HeapStatsParser parser = new HeapStatsParser();
            StringBuilder fileList = new StringBuilder();

            for (File file : fileDlg.getSelectedFiles()) {
                fileList.append(" ");
                fileList.append(file.getName());
                fileList.append(",");

                ParserEventHandlerImpl handler = new ParserEventHandlerImpl();

                if (!parser.parse(file.getAbsolutePath(), handler)) {
                    return false;
                }
                offsets.putAll(handler.getSnapShotList());
            }

            fileName.setText(fileList.toString().substring(0,
                    fileList.length() - 1));
        } catch (Exception e) {
            e.printStackTrace();
            GuiCommon.showMessage(this, GuiCommon.BASEE08, e.getMessage(),
                    JOptionPane.ERROR_MESSAGE);

            return false;
        }
        return true;
    }

    /**
     * Snapshot information to draw the tab in the dialog had been separated.
     */
    private void setSelectData() {
        Vector<String> snapList = new Vector<String>();

        startCombo.removeAllItems();
        endCombo.removeAllItems();

        SimpleDateFormat sdf = new SimpleDateFormat(GuiCommon.DATE_FORMAT);
        for (Map.Entry<Date, String> entry : offsets.entrySet()) {
            startCombo.addItem(addObject(sdf.format(entry.getKey())));
            endCombo.addItem(addObject(sdf.format(entry.getKey())));
            snapList.add(sdf.format(entry.getKey()));
        }
        startCombo.setSelectedIndex(0);
        endCombo.setSelectedIndex(endCombo.getItemCount() - 1);

        // KeyListener
        // Set SELECT RANGE combobox
        SnapshotDateListener start = new SnapshotDateListener(startCombo);
        start.setSnapList(snapList);
        JTextField startTxt = (JTextField) startCombo.getEditor()
                .getEditorComponent();
        startTxt.setText(startCombo.getItemAt(0).toString());
        startTxt.addKeyListener(start);

        SnapshotDateListener end = new SnapshotDateListener(endCombo);
        end.setSnapList(snapList);
        JTextField endTxt = (JTextField) endCombo.getEditor()
                .getEditorComponent();
        endTxt.setText(endCombo.getItemAt(endCombo.getItemCount() - 1)
                .toString());
        endTxt.addKeyListener(end);

        if (tabbedBar.isSelected()) {
            snapshotTabbed.add(
                    GuiCommon.getResources().getString(
                            GuiCommon.TAB_TITLE_SUMMARY), gcComp);
            snapshotTabbed.add(
                    GuiCommon.getResources()
                            .getString(GuiCommon.TAB_TITLE_DELA), deltaComp);
            snapshotTabbed.add(
                    GuiCommon.getResources().getString(
                            GuiCommon.TAB_TITLE_SNAPSHOT), snapComp);
            snapshotTabbed.add(
                    GuiCommon.getResources().getString(
                            GuiCommon.TAB_TITLE_REFERENCE), refComp);
        }
    }

    /**
     * Converts a string to an object of The snapshot date.
     *
     * @param item The snapshot Date
     * @return The snapshot Date object
     */
    private Object addObject(final String item) {
        return new Object() {
            public String toString() {
                return item;
            }
        };
    }

    /**
     * Sets the Ranking Level.
     */
    private void setRankLevel() {
        try {
            Object rank = JOptionPane.showInputDialog(this, GuiCommon
                    .getResources().getString(GuiCommon.RANK_LEVEL),
                    GuiCommon.ANALYZER_TITLE, JOptionPane.QUESTION_MESSAGE,
                    null, null, GuiCommon.getRankLevel());
            if (rank == null) {
                return;
            }

            int buf = Integer.parseInt((String) rank);
            if (buf > 0) {
                GuiCommon.setRankLevel(buf);
            } else {
                GuiCommon.showMessage(this, GuiCommon.BASEE02,
                        JOptionPane.ERROR_MESSAGE);
            }
        } catch (NumberFormatException e) {
            GuiCommon.showMessage(this, GuiCommon.BASEE01,
                    JOptionPane.ERROR_MESSAGE);
        } catch (IOException e) {
            GuiCommon.showMessage(this, GuiCommon.BASEE17,
                    JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * CSV output to the snapshot.
     *
     * @param type dump type true:java heap csv
     * @param allDump The output period of CSV. true: all output
     */
    private void dumpCsv(final boolean type, final boolean allDump) {
        // Java Heap CSV
        int start = startCombo.getSelectedIndex();
        int end = endCombo.getSelectedIndex();
        if (!allDump) {
            if (!selectRange(start, end)) {
                return;
            }
        } else {
            if (offsets.size() == 0) {
                GuiCommon.showMessage(this, GuiCommon.BASEE03,
                        JOptionPane.ERROR_MESSAGE);
                return;
            }
        }

        JFileChooser fileDlg = new JFileChooser();
        fileDlg.setCurrentDirectory(GuiCommon.getCurrentDir());
        fileDlg.setAcceptAllFileFilterUsed(false);
        fileDlg.setFileFilter(new FileNameExtensionFilter("CSV", "csv"));

        if (fileDlg.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
            return;
        }

        try {
            GuiCommon.setCurrentDir(fileDlg.getCurrentDirectory());
        } catch (IOException e) {
            GuiCommon.showMessage(this, GuiCommon.BASEE17,
                    JOptionPane.ERROR_MESSAGE);
        }
        List<String> diffOffsets = new ArrayList<String>();
        if (!allDump) {
            int i = 0;
            for (Map.Entry<Date, String> entry : offsets.entrySet()) {
                if (i >= start && i <= end) {
                    diffOffsets.add(entry.getValue());
                }
                i++;
            }
        } else {
            diffOffsets.addAll(offsets.values());
        }

        dumper = new CSVDumper(this);
        dumper.setCsvFile(fileDlg.getSelectedFile().getPath());
        dumper.setDiffOffsets(diffOffsets);
        dumper.setDumpType(type);
        dumper.setDelta(deltaDlg);
        dumper.execute();
    }

    /**
     * Displays the simple manual.
     */
    private void popupManual() {
        try {
            File file = new File(GuiCommon.getResources().getString(
                    GuiCommon.HOWTO_TEXT));
            Desktop desk = Desktop.getDesktop();
            desk.open(file);
        } catch (Exception e) {
            GuiCommon.showMessage(this, GuiCommon.BASEE18,
                    JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * Clear the offsets.
     *
     * @throws IOException If an I/O error has occurred.
     */
    private void clearOffsets() throws IOException {
        offsets.clear();
    }

    /**
     * Start HeapStats Analyzer.
     *
     * @param args the arguments used for the method call
     */
    public static void main(final String[] args) {
        final GUIMain mainWnd = new GUIMain(GuiCommon.ANALYZER_TITLE);
        mainWnd.setVisible(true);

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                mainWnd.validate();
            }
        });
    }
}