001: /*
002: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.jconsole;
027:
028: import java.awt.*;
029: import java.awt.event.*;
030: import java.io.*;
031: import java.lang.management.*;
032: import java.lang.reflect.*;
033:
034: import javax.swing.*;
035: import javax.swing.border.*;
036: import javax.swing.event.*;
037: import javax.swing.text.*;
038:
039: import java.util.*;
040: import java.util.List;
041: import java.util.concurrent.*;
042:
043: import sun.awt.*;
044:
045: import static sun.tools.jconsole.Formatter.*;
046: import static sun.tools.jconsole.Resources.*;
047: import static sun.tools.jconsole.Utilities.*;
048:
049: @SuppressWarnings("serial")
050: class ClassTab extends Tab implements ActionListener {
051: PlotterPanel loadedClassesMeter;
052: TimeComboBox timeComboBox;
053: private JCheckBox verboseCheckBox;
054: private HTMLPane details;
055: private ClassOverviewPanel overviewPanel;
056: private boolean plotterListening = false;
057:
058: private static final String loadedPlotterKey = "loaded";
059: private static final String totalLoadedPlotterKey = "totalLoaded";
060: private static final String loadedPlotterName = Resources
061: .getText("Loaded");
062: private static final String totalLoadedPlotterName = Resources
063: .getText("Total Loaded");
064: private static final Color loadedPlotterColor = Plotter.defaultColor;
065: private static final Color totalLoadedPlotterColor = Color.red;
066:
067: private static final String infoLabelFormat = "ClassTab.infoLabelFormat";
068:
069: /*
070: Hierarchy of panels and layouts for this tab:
071:
072: ClassTab (BorderLayout)
073:
074: North: topPanel (BorderLayout)
075:
076: Center: controlPanel (FlowLayout)
077: timeComboBox
078:
079: East: topRightPanel (FlowLayout)
080: verboseCheckBox
081:
082: Center: plotterPanel (BorderLayout)
083:
084: Center: plotter
085:
086: South: bottomPanel (BorderLayout)
087:
088: Center: details
089: */
090:
091: public static String getTabName() {
092: return Resources.getText("Classes");
093: }
094:
095: public ClassTab(VMPanel vmPanel) {
096: super (vmPanel, getTabName());
097:
098: setLayout(new BorderLayout(0, 0));
099: setBorder(new EmptyBorder(4, 4, 3, 4));
100:
101: JPanel topPanel = new JPanel(new BorderLayout());
102: JPanel plotterPanel = new JPanel(new BorderLayout());
103: JPanel bottomPanel = new JPanel(new BorderLayout());
104:
105: add(topPanel, BorderLayout.NORTH);
106: add(plotterPanel, BorderLayout.CENTER);
107: add(bottomPanel, BorderLayout.SOUTH);
108:
109: JPanel controlPanel = new JPanel(new FlowLayout(
110: FlowLayout.CENTER, 20, 5));
111: topPanel.add(controlPanel, BorderLayout.CENTER);
112:
113: verboseCheckBox = new JCheckBox(Resources
114: .getText("Verbose Output"));
115: verboseCheckBox.addActionListener(this );
116: verboseCheckBox
117: .setToolTipText(getText("Verbose Output.toolTip"));
118: JPanel topRightPanel = new JPanel();
119: topRightPanel.setBorder(new EmptyBorder(0, 65 - 8, 0, 70));
120: topRightPanel.add(verboseCheckBox);
121: topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
122:
123: loadedClassesMeter = new PlotterPanel(Resources
124: .getText("Number of Loaded Classes"),
125: Plotter.Unit.NONE, false);
126: loadedClassesMeter.plotter.createSequence(loadedPlotterKey,
127: loadedPlotterName, loadedPlotterColor, true);
128: loadedClassesMeter.plotter.createSequence(
129: totalLoadedPlotterKey, totalLoadedPlotterName,
130: totalLoadedPlotterColor, true);
131: setAccessibleName(loadedClassesMeter.plotter,
132: getText("ClassTab.loadedClassesPlotter.accessibleName"));
133: plotterPanel.add(loadedClassesMeter);
134:
135: timeComboBox = new TimeComboBox(loadedClassesMeter.plotter);
136: controlPanel.add(new LabeledComponent(Resources
137: .getText("Time Range:"), getMnemonicInt("Time Range:"),
138: timeComboBox));
139:
140: LabeledComponent.layout(plotterPanel);
141:
142: bottomPanel.setBorder(new CompoundBorder(new TitledBorder(
143: Resources.getText("Details")), new EmptyBorder(10, 10,
144: 10, 10)));
145:
146: details = new HTMLPane();
147: setAccessibleName(details, getText("Details"));
148: JScrollPane scrollPane = new JScrollPane(details);
149: scrollPane.setPreferredSize(new Dimension(0, 150));
150: bottomPanel.add(scrollPane, BorderLayout.SOUTH);
151:
152: }
153:
154: public void actionPerformed(ActionEvent ev) {
155: final boolean b = verboseCheckBox.isSelected();
156: workerAdd(new Runnable() {
157: public void run() {
158: ProxyClient proxyClient = vmPanel.getProxyClient();
159: try {
160: proxyClient.getClassLoadingMXBean().setVerbose(b);
161: } catch (UndeclaredThrowableException e) {
162: proxyClient.markAsDead();
163: } catch (IOException ex) {
164: // Ignore
165: }
166: }
167: });
168: }
169:
170: public SwingWorker<?, ?> newSwingWorker() {
171: final ProxyClient proxyClient = vmPanel.getProxyClient();
172:
173: if (!plotterListening) {
174: proxyClient
175: .addWeakPropertyChangeListener(loadedClassesMeter.plotter);
176: plotterListening = true;
177: }
178:
179: return new SwingWorker<Boolean, Object>() {
180: private long clCount, cuCount, ctCount;
181: private boolean isVerbose;
182: private String detailsStr;
183: private long timeStamp;
184:
185: public Boolean doInBackground() {
186: try {
187: ClassLoadingMXBean classLoadingMBean = proxyClient
188: .getClassLoadingMXBean();
189:
190: clCount = classLoadingMBean.getLoadedClassCount();
191: cuCount = classLoadingMBean.getUnloadedClassCount();
192: ctCount = classLoadingMBean
193: .getTotalLoadedClassCount();
194: isVerbose = classLoadingMBean.isVerbose();
195: detailsStr = formatDetails();
196: timeStamp = System.currentTimeMillis();
197:
198: return true;
199: } catch (UndeclaredThrowableException e) {
200: proxyClient.markAsDead();
201: return false;
202: } catch (IOException e) {
203: return false;
204: }
205: }
206:
207: protected void done() {
208: try {
209: if (get()) {
210: loadedClassesMeter.plotter.addValues(timeStamp,
211: clCount, ctCount);
212:
213: if (overviewPanel != null) {
214: overviewPanel.updateClassInfo(ctCount,
215: clCount);
216: overviewPanel.getPlotter().addValues(
217: timeStamp, clCount);
218: }
219:
220: loadedClassesMeter.setValueLabel(clCount + "");
221: verboseCheckBox.setSelected(isVerbose);
222: details.setText(detailsStr);
223: }
224: } catch (InterruptedException ex) {
225: } catch (ExecutionException ex) {
226: if (JConsole.isDebug()) {
227: ex.printStackTrace();
228: }
229: }
230: }
231:
232: private String formatDetails() {
233: String text = "<table cellspacing=0 cellpadding=0>";
234:
235: long time = System.currentTimeMillis();
236: String timeStamp = formatDateTime(time);
237: text += newRow(Resources.getText("Time"), timeStamp);
238: text += newRow(Resources
239: .getText("Current classes loaded"), justify(
240: clCount, 5));
241: text += newRow(Resources
242: .getText("Total classes loaded"), justify(
243: ctCount, 5));
244: text += newRow(Resources
245: .getText("Total classes unloaded"), justify(
246: cuCount, 5));
247:
248: return text;
249: }
250: };
251: }
252:
253: OverviewPanel[] getOverviewPanels() {
254: if (overviewPanel == null) {
255: overviewPanel = new ClassOverviewPanel();
256: }
257: return new OverviewPanel[] { overviewPanel };
258: }
259:
260: private static class ClassOverviewPanel extends OverviewPanel {
261: ClassOverviewPanel() {
262: super (getText("Classes"), loadedPlotterKey,
263: loadedPlotterName, null);
264: }
265:
266: private void updateClassInfo(long total, long loaded) {
267: long unloaded = (total - loaded);
268: getInfoLabel().setText(
269: getText(infoLabelFormat, loaded, unloaded, total));
270: }
271: }
272: }
|