src/jdk.jconsole/share/classes/sun/tools/jconsole/ClassTab.java
changeset 47216 71c04702a3d5
parent 25859 3317bb8137f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jconsole/share/classes/sun/tools/jconsole/ClassTab.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,248 @@
+/*
+ * 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));
+        }
+    }
+}