0N/A/*
2362N/A * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.tools.jconsole;
0N/A
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.io.*;
0N/Aimport java.lang.management.*;
0N/Aimport java.lang.reflect.*;
0N/A
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.border.*;
0N/A
5335N/A
0N/Aimport java.util.concurrent.*;
0N/A
0N/Aimport static sun.tools.jconsole.Formatter.*;
0N/Aimport static sun.tools.jconsole.Utilities.*;
0N/A
0N/A
0N/A@SuppressWarnings("serial")
0N/Aclass ClassTab extends Tab implements ActionListener {
0N/A PlotterPanel loadedClassesMeter;
0N/A TimeComboBox timeComboBox;
0N/A private JCheckBox verboseCheckBox;
0N/A private HTMLPane details;
0N/A private ClassOverviewPanel overviewPanel;
0N/A private boolean plotterListening = false;
0N/A
0N/A private static final String loadedPlotterKey = "loaded";
0N/A private static final String totalLoadedPlotterKey = "totalLoaded";
0N/A private static final Color loadedPlotterColor = Plotter.defaultColor;
0N/A private static final Color totalLoadedPlotterColor = Color.red;
0N/A
0N/A /*
0N/A Hierarchy of panels and layouts for this tab:
0N/A
0N/A ClassTab (BorderLayout)
0N/A
0N/A North: topPanel (BorderLayout)
0N/A
0N/A Center: controlPanel (FlowLayout)
0N/A timeComboBox
0N/A
0N/A East: topRightPanel (FlowLayout)
0N/A verboseCheckBox
0N/A
0N/A Center: plotterPanel (BorderLayout)
0N/A
0N/A Center: plotter
0N/A
0N/A South: bottomPanel (BorderLayout)
0N/A
0N/A Center: details
0N/A */
0N/A
0N/A public static String getTabName() {
5335N/A return Messages.CLASSES;
0N/A }
0N/A
0N/A public ClassTab(VMPanel vmPanel) {
0N/A super(vmPanel, getTabName());
0N/A
0N/A setLayout(new BorderLayout(0, 0));
0N/A setBorder(new EmptyBorder(4, 4, 3, 4));
0N/A
0N/A JPanel topPanel = new JPanel(new BorderLayout());
0N/A JPanel plotterPanel = new JPanel(new BorderLayout());
0N/A JPanel bottomPanel = new JPanel(new BorderLayout());
0N/A
0N/A add(topPanel, BorderLayout.NORTH);
0N/A add(plotterPanel, BorderLayout.CENTER);
0N/A add(bottomPanel, BorderLayout.SOUTH);
0N/A
0N/A JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
0N/A topPanel.add(controlPanel, BorderLayout.CENTER);
0N/A
5335N/A verboseCheckBox = new JCheckBox(Messages.VERBOSE_OUTPUT);
0N/A verboseCheckBox.addActionListener(this);
5335N/A verboseCheckBox.setToolTipText(Messages.VERBOSE_OUTPUT_TOOLTIP);
0N/A JPanel topRightPanel = new JPanel();
0N/A topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
0N/A topRightPanel.add(verboseCheckBox);
0N/A topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
0N/A
5335N/A loadedClassesMeter = new PlotterPanel(Messages.NUMBER_OF_LOADED_CLASSES,
0N/A Plotter.Unit.NONE, false);
0N/A loadedClassesMeter.plotter.createSequence(loadedPlotterKey,
5335N/A Messages.LOADED,
0N/A loadedPlotterColor,
0N/A true);
0N/A loadedClassesMeter.plotter.createSequence(totalLoadedPlotterKey,
5335N/A Messages.TOTAL_LOADED,
0N/A totalLoadedPlotterColor,
0N/A true);
0N/A setAccessibleName(loadedClassesMeter.plotter,
5335N/A Messages.CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME);
0N/A plotterPanel.add(loadedClassesMeter);
0N/A
0N/A timeComboBox = new TimeComboBox(loadedClassesMeter.plotter);
5335N/A controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
5335N/A Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
0N/A timeComboBox));
0N/A
0N/A LabeledComponent.layout(plotterPanel);
0N/A
5335N/A bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
5335N/A new EmptyBorder(10, 10, 10, 10)));
0N/A
0N/A details = new HTMLPane();
5335N/A setAccessibleName(details, Messages.DETAILS);
0N/A JScrollPane scrollPane = new JScrollPane(details);
0N/A scrollPane.setPreferredSize(new Dimension(0, 150));
0N/A bottomPanel.add(scrollPane, BorderLayout.SOUTH);
0N/A
0N/A }
0N/A
0N/A public void actionPerformed(ActionEvent ev) {
0N/A final boolean b = verboseCheckBox.isSelected();
0N/A workerAdd(new Runnable() {
0N/A public void run() {
0N/A ProxyClient proxyClient = vmPanel.getProxyClient();
0N/A try {
0N/A proxyClient.getClassLoadingMXBean().setVerbose(b);
0N/A } catch (UndeclaredThrowableException e) {
0N/A proxyClient.markAsDead();
0N/A } catch (IOException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A });
0N/A }
0N/A
0N/A
0N/A public SwingWorker<?, ?> newSwingWorker() {
0N/A final ProxyClient proxyClient = vmPanel.getProxyClient();
0N/A
0N/A if (!plotterListening) {
0N/A proxyClient.addWeakPropertyChangeListener(loadedClassesMeter.plotter);
0N/A plotterListening = true;
0N/A }
0N/A
0N/A return new SwingWorker<Boolean, Object>() {
0N/A private long clCount, cuCount, ctCount;
0N/A private boolean isVerbose;
0N/A private String detailsStr;
0N/A private long timeStamp;
0N/A
0N/A public Boolean doInBackground() {
0N/A try {
0N/A ClassLoadingMXBean classLoadingMBean = proxyClient.getClassLoadingMXBean();
0N/A
0N/A clCount = classLoadingMBean.getLoadedClassCount();
0N/A cuCount = classLoadingMBean.getUnloadedClassCount();
0N/A ctCount = classLoadingMBean.getTotalLoadedClassCount();
0N/A isVerbose = classLoadingMBean.isVerbose();
0N/A detailsStr = formatDetails();
0N/A timeStamp = System.currentTimeMillis();
0N/A
0N/A return true;
0N/A } catch (UndeclaredThrowableException e) {
0N/A proxyClient.markAsDead();
0N/A return false;
0N/A } catch (IOException e) {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A protected void done() {
0N/A try {
0N/A if (get()) {
0N/A loadedClassesMeter.plotter.addValues(timeStamp, clCount, ctCount);
0N/A
0N/A if (overviewPanel != null) {
0N/A overviewPanel.updateClassInfo(ctCount, clCount);
0N/A overviewPanel.getPlotter().addValues(timeStamp, clCount);
0N/A }
0N/A
0N/A loadedClassesMeter.setValueLabel(clCount + "");
0N/A verboseCheckBox.setSelected(isVerbose);
0N/A details.setText(detailsStr);
0N/A }
0N/A } catch (InterruptedException ex) {
0N/A } catch (ExecutionException ex) {
0N/A if (JConsole.isDebug()) {
0N/A ex.printStackTrace();
0N/A }
0N/A }
0N/A }
0N/A
0N/A private String formatDetails() {
0N/A String text = "<table cellspacing=0 cellpadding=0>";
0N/A
0N/A long time = System.currentTimeMillis();
0N/A String timeStamp = formatDateTime(time);
5335N/A text += newRow(Messages.TIME, timeStamp);
5335N/A text += newRow(Messages.CURRENT_CLASSES_LOADED, justify(clCount, 5));
5335N/A text += newRow(Messages.TOTAL_CLASSES_LOADED, justify(ctCount, 5));
5335N/A text += newRow(Messages.TOTAL_CLASSES_UNLOADED, justify(cuCount, 5));
0N/A
0N/A return text;
0N/A }
0N/A };
0N/A }
0N/A
0N/A
0N/A OverviewPanel[] getOverviewPanels() {
0N/A if (overviewPanel == null) {
0N/A overviewPanel = new ClassOverviewPanel();
0N/A }
0N/A return new OverviewPanel[] { overviewPanel };
0N/A }
0N/A
0N/A private static class ClassOverviewPanel extends OverviewPanel {
0N/A ClassOverviewPanel() {
5335N/A super(Messages.CLASSES, loadedPlotterKey, Messages.LOADED, null);
0N/A }
0N/A
0N/A private void updateClassInfo(long total, long loaded) {
0N/A long unloaded = (total - loaded);
5335N/A getInfoLabel().setText(Resources.format(Messages.CLASS_TAB_INFO_LABEL_FORMAT,
5335N/A loaded, unloaded, total));
0N/A }
0N/A }
0N/A}