| /* | |
| * 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)); | |
| } | |
| } | |
| } |