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