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