/* * Copyright (c) 2007, 2011, 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 com.sun.tools.visualvm.application.views.monitor; import com.sun.tools.visualvm.application.Application; import com.sun.tools.visualvm.core.datasupport.DataRemovedListener; import com.sun.tools.visualvm.charts.ChartFactory; import com.sun.tools.visualvm.charts.SimpleXYChartDescriptor; import com.sun.tools.visualvm.charts.SimpleXYChartSupport; import com.sun.tools.visualvm.core.datasource.DataSource; import com.sun.tools.visualvm.core.datasupport.Stateful; import com.sun.tools.visualvm.core.ui.DataSourceView; import com.sun.tools.visualvm.core.ui.components.DataViewComponent; import com.sun.tools.visualvm.core.ui.components.NotSupportedDisplayer; import com.sun.tools.visualvm.heapdump.HeapDumpSupport; import com.sun.tools.visualvm.uisupport.HTMLTextArea; import java.awt.BorderLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; import org.openide.util.WeakListeners; /** * * @author Jiri Sedlacek */ class ApplicationMonitorView extends DataSourceView { private static final Logger LOGGER = Logger.getLogger(ApplicationMonitorView.class.getName()); private static final String UNKNOWN = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Unknown"); // NOI18N private static final String IMAGE_PATH = "com/sun/tools/visualvm/application/views/resources/monitor.png"; // NOI18N private final ApplicationMonitorModel model; public ApplicationMonitorView(ApplicationMonitorModel model) { super(model.getSource(), NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Monitor"), new ImageIcon(ImageUtilities. // NOI18N loadImage(IMAGE_PATH, true)).getImage(), 20, false); this.model = model; } protected void willBeAdded() { model.initialize(); } protected void removed() { model.cleanup(); } ApplicationMonitorModel getModel() { return model; } protected DataViewComponent createComponent() { final MasterViewSupport masterViewSupport = new MasterViewSupport(model); DataViewComponent dvc = new DataViewComponent( masterViewSupport.getMasterView(), new DataViewComponent.MasterViewConfiguration(false)); final CpuViewSupport cpuViewSupport = new CpuViewSupport(model); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle. getMessage(ApplicationMonitorView.class, "LBL_Cpu"), true), DataViewComponent.TOP_LEFT); // NOI18N dvc.addDetailsView(cpuViewSupport.getDetailsView(), DataViewComponent.TOP_LEFT); final HeapViewSupport heapViewSupport = new HeapViewSupport(model); final PermGenViewSupport permGenViewSupport = new PermGenViewSupport(model); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle. getMessage(ApplicationMonitorView.class, "LBL_Memory"), true), DataViewComponent.TOP_RIGHT); // NOI18N dvc.addDetailsView(heapViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT); dvc.addDetailsView(permGenViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT); final ClassesViewSupport classesViewSupport = new ClassesViewSupport(model); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle. getMessage(ApplicationMonitorView.class, "LBL_Classes"), true), DataViewComponent.BOTTOM_LEFT); // NOI18N dvc.addDetailsView(classesViewSupport.getDetailsView(), DataViewComponent.BOTTOM_LEFT); final ThreadsViewSupport threadsViewSupport = new ThreadsViewSupport(model); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle. getMessage(ApplicationMonitorView.class, "LBL_Threads"), true), DataViewComponent.BOTTOM_RIGHT); // NOI18N dvc.addDetailsView(threadsViewSupport.getDetailsView(), DataViewComponent.BOTTOM_RIGHT); final Runnable refresher = new Runnable() { public void run() { masterViewSupport.refresh(model); cpuViewSupport.refresh(model); heapViewSupport.refresh(model); permGenViewSupport.refresh(model); classesViewSupport.refresh(model); threadsViewSupport.refresh(model); } }; refresher.run(); model.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { refresher.run(); } }); return dvc; } // --- General data -------------------------------------------------------- private static class MasterViewSupport extends JPanel implements DataRemovedListener<DataSource>, PropertyChangeListener { private HTMLTextArea area; private JButton gcButton; private JButton heapDumpButton; public MasterViewSupport(ApplicationMonitorModel model) { initComponents(model); } public DataViewComponent.MasterView getMasterView() { return new DataViewComponent.MasterView(NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Monitor"), null, this); // NOI18N } public void refresh(ApplicationMonitorModel model) { int selStart = area.getSelectionStart(); int selEnd = area.getSelectionEnd(); area.setText(getBasicTelemetry(model)); area.select(selStart, selEnd); } public void dataRemoved(DataSource dataSource) { SwingUtilities.invokeLater(new Runnable() { public void run() { gcButton.setEnabled(false); heapDumpButton.setEnabled(false); } }); } public void propertyChange(PropertyChangeEvent evt) { dataRemoved(null); } private void initComponents(final ApplicationMonitorModel model) { setLayout(new BorderLayout()); setOpaque(false); area = new HTMLTextArea(getBasicTelemetry(model)); area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8)); add(area, BorderLayout.CENTER); gcButton = new JButton(new AbstractAction(NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Perform_GC")) { // NOI18N public void actionPerformed(ActionEvent e) { RequestProcessor.getDefault().post(new Runnable() { public void run() { try { model.getMemoryMXBean().gc(); } catch (SecurityException ex) { String err = NbBundle.getMessage(ApplicationMonitorView.class, "TXT_Perform_GC_failed", ex.getLocalizedMessage()); // NOI18N NotifyDescriptor nd = new NotifyDescriptor.Message(err, NotifyDescriptor.INFORMATION_MESSAGE); DialogDisplayer.getDefault().notify(nd); gcButton.setEnabled(false); } catch (Exception e) { LOGGER.log(Level.WARNING, "initComponents", e); // NOI18N gcButton.setEnabled(false); } }; }); } }); gcButton.setEnabled(model.getMemoryMXBean() != null); heapDumpButton = new JButton(new AbstractAction(NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Heap_Dump")) { // NOI18N public void actionPerformed(ActionEvent e) { Application application = (Application)model.getSource(); boolean local = application.isLocalApplication(); boolean tagged = (e.getModifiers() & Toolkit.getDefaultToolkit(). getMenuShortcutKeyMask()) != 0; HeapDumpSupport hds = HeapDumpSupport.getInstance(); if (local) hds.takeHeapDump(application, !tagged); else hds.takeRemoteHeapDump(application, null, !tagged); } }); heapDumpButton.setEnabled(model.isTakeHeapDumpSupported()); JPanel buttonsArea = new JPanel(new BorderLayout()); buttonsArea.setOpaque(false); JPanel buttonsContainer = new JPanel(new BorderLayout(3, 0)); buttonsContainer.setBackground(area.getBackground()); buttonsContainer.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8)); buttonsContainer.add(gcButton, BorderLayout.WEST); buttonsContainer.add(heapDumpButton, BorderLayout.EAST); buttonsArea.add(buttonsContainer, BorderLayout.NORTH); add(buttonsArea, BorderLayout.AFTER_LINE_ENDS); if (model.getSource() instanceof Application) { Application application = (Application)model.getSource(); application.notifyWhenRemoved(this); application.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(this,application)); } } private String getBasicTelemetry(ApplicationMonitorModel model) { String uptime = model.getUpTime() == -1 ? UNKNOWN : getTime(model.getUpTime()); return NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Uptime", uptime); // NOI18N } public static String getTime(long millis) { // Hours long hours = millis / 3600000; String sHours = (hours == 0 ? "" : "" + hours); // NOI18N millis = millis % 3600000; // Minutes long minutes = millis / 60000; String sMinutes = (((hours > 0) && (minutes < 10)) ? "0" + minutes : "" + minutes); // NOI18N millis = millis % 60000; // Seconds long seconds = millis / 1000; String sSeconds = ((seconds < 10) ? "0" + seconds : "" + seconds); // NOI18N if (sHours.length() == 0) { return NbBundle.getMessage(ApplicationMonitorView.class, "FORMAT_ms", // NOI18N new Object[] { sMinutes, sSeconds }); } else { return NbBundle.getMessage(ApplicationMonitorView.class, "FORMAT_hms", // NOI18N new Object[] { sHours, sMinutes, sSeconds }); } } } // --- CPU ----------------------------------------------------------------- private static class CpuViewSupport extends JPanel { private static final String CPU = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Cpu"); // NOI18N private static final String CPU_USAGE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Cpu_Usage"); // NOI18N private static final String GC_USAGE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Gc_Usage"); // NOI18N private boolean liveModel; private int processorsCount; private boolean cpuMonitoringSupported; private boolean gcMonitoringSupported; private SimpleXYChartSupport chartSupport; public CpuViewSupport(ApplicationMonitorModel model) { initModels(model); initComponents(model); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(CPU, null, 10, this, null); } public void refresh(ApplicationMonitorModel model) { if (cpuMonitoringSupported || gcMonitoringSupported) { long upTime = model.getUpTime() * 1000000; long prevUpTime = model.getPrevUpTime() * 1000000; boolean tracksProcessCpuTime = cpuMonitoringSupported && model.getPrevProcessCpuTime() != -1; long processCpuTime = tracksProcessCpuTime ? model.getProcessCpuTime() / processorsCount : -1; long prevProcessCpuTime = tracksProcessCpuTime ? model.getPrevProcessCpuTime() / processorsCount : -1; boolean tracksProcessGcTime = gcMonitoringSupported && model.getPrevProcessGcTime() != -1; long processGcTime = tracksProcessGcTime ? model.getProcessGcTime() * 1000000 / processorsCount : -1; long prevProcessGcTime = tracksProcessGcTime ? model.getPrevProcessGcTime() * 1000000 / processorsCount : -1; if (prevUpTime != -1 && (tracksProcessCpuTime || tracksProcessGcTime)) { long upTimeDiff = upTime - prevUpTime; long cpuUsage = -1; long gcUsage = -1; String cpuDetail = UNKNOWN; String gcDetail = UNKNOWN; if (tracksProcessCpuTime) { long processTimeDiff = processCpuTime - prevProcessCpuTime; cpuUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processTimeDiff / (float)upTimeDiff), 1000) : 0; cpuDetail = cpuUsage == -1 ? UNKNOWN : chartSupport.formatPercent(cpuUsage); } if (tracksProcessGcTime) { long processGcTimeDiff = processGcTime - prevProcessGcTime; gcUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processGcTimeDiff / (float)upTimeDiff), 1000) : 0; if (cpuUsage != -1 && cpuUsage < gcUsage) gcUsage = cpuUsage; gcDetail = gcUsage == -1 ? UNKNOWN : chartSupport.formatPercent(gcUsage); } if (liveModel) chartSupport.addValues(model.getTimestamp(), new long[] { Math.max(cpuUsage, 0), Math.max(gcUsage, 0) }); chartSupport.updateDetails(new String[] { cpuDetail, gcDetail }); } } } private void initModels(ApplicationMonitorModel model) { liveModel = model.isLive(); processorsCount = model.getProcessorsCount(); cpuMonitoringSupported = model.isCpuMonitoringSupported(); gcMonitoringSupported = model.isGcMonitoringSupported(); SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.percent(false, 0.1d, model.getChartCache()); chartDescriptor.addLineItems(CPU_USAGE, GC_USAGE); chartDescriptor.setDetailsItems(new String[] { CPU_USAGE, GC_USAGE }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); model.registerCpuChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); } private void initComponents(ApplicationMonitorModel model) { setLayout(new BorderLayout()); setOpaque(false); if (model.isCpuMonitoringSupported() || model.isGcMonitoringSupported()) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN }); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } // --- Heap ---------------------------------------------------------------- private static class HeapViewSupport extends JPanel { private boolean liveModel; private boolean memoryMonitoringSupported; private String heapName; private SimpleXYChartSupport chartSupport; public HeapViewSupport(ApplicationMonitorModel model) { initModels(model); initComponents(model); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(heapName, null, 10, this, null); } public void refresh(ApplicationMonitorModel model) { if (memoryMonitoringSupported) { long heapCapacity = model.getHeapCapacity(); long heapUsed = model.getHeapUsed(); long maxHeap = model.getMaxHeap(); if (liveModel) chartSupport.addValues(model.getTimestamp(), new long[] { heapCapacity, heapUsed }); chartSupport.updateDetails(new String[] { chartSupport.formatBytes(heapCapacity), chartSupport.formatBytes(heapUsed), chartSupport.formatBytes(maxHeap) }); } } private void initModels(ApplicationMonitorModel model) { liveModel = model.isLive(); memoryMonitoringSupported = model.isMemoryMonitoringSupported(); heapName = model.getHeapName(); String HEAP_SIZE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Heap_size"); // NOI18N String HEAP_SIZE_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Heap_size_leg",heapName); // NOI18N String USED_HEAP = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Used_heap"); // NOI18N String USED_HEAP_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Used_heap_leg",heapName.toLowerCase()); // NOI18N String MAX_HEAP = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Max_Heap"); // NOI18N SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, model.getChartCache()); chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG); chartDescriptor.setDetailsItems(new String[] { HEAP_SIZE, USED_HEAP, MAX_HEAP }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); model.registerHeapChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); } private void initComponents(ApplicationMonitorModel model) { setLayout(new BorderLayout()); setOpaque(false); if (model.isMemoryMonitoringSupported()) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN }); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } // --- PermGen ------------------------------------------------------------- private static class PermGenViewSupport extends JPanel { private boolean liveModel; private boolean memoryMonitoringSupported; private String permgenName; private SimpleXYChartSupport chartSupport; public PermGenViewSupport(ApplicationMonitorModel model) { initModels(model); initComponents(model); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(permgenName, null, 10, this, null); } public void refresh(ApplicationMonitorModel model) { if (memoryMonitoringSupported) { long permgenCapacity = model.getPermgenCapacity(); long permgenUsed = model.getPermgenUsed(); long permgenMax = model.getPermgenMax(); if (liveModel) chartSupport.addValues(model.getTimestamp(), new long[] { permgenCapacity, permgenUsed }); chartSupport.updateDetails(new String[] { chartSupport.formatBytes(permgenCapacity), chartSupport.formatBytes(permgenUsed), chartSupport.formatBytes(permgenMax) }); } } private void initModels(ApplicationMonitorModel model) { liveModel = model.isLive(); memoryMonitoringSupported = model.isMemoryMonitoringSupported(); permgenName = model.getPermgenName(); String PERM_SIZE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_PermGen_size"); // NOI18N String PERM_SIZE_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_PermGen_size_leg", permgenName); // NOI18N String USED_PERM = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Used_PermGen"); // NOI18N String USED_PERM_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Used_PermGen_leg", permgenName); // NOI18N String MAX_PERM = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Max_PermGen_size"); // NOI18N SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, model.getChartCache()); chartDescriptor.addLineFillItems(PERM_SIZE_LEG, USED_PERM_LEG); chartDescriptor.setDetailsItems(new String[] { PERM_SIZE, USED_PERM, MAX_PERM }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); model.registerPermGenChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); } private void initComponents(ApplicationMonitorModel model) { setLayout(new BorderLayout()); setOpaque(false); if (model.isMemoryMonitoringSupported()) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN }); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } // --- Classes ------------------------------------------------------------- private static class ClassesViewSupport extends JPanel { private static final String TOTAL_LOADED = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Total_loaded_classes"); // NOI18N private static final String TOTAL_LOADED_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Total_loaded_classes_leg"); // NOI18N private static final String SHARED_LOADED = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Shared_loaded_classes"); // NOI18N private static final String SHARED_LOADED_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Shared_loaded_classes_leg"); // NOI18N private static final String TOTAL_UNLOADED = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Total_unloaded_classes"); // NOI18N private static final String SHARED_UNLOADED = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Shared_unloaded_classes"); // NOI18N private boolean liveModel; private boolean classMonitoringSupported; private SimpleXYChartSupport chartSupport; public ClassesViewSupport(ApplicationMonitorModel model) { initModels(model); initComponents(model); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Classes"), null, 10, this, null); // NOI18N } public void refresh(ApplicationMonitorModel model) { if (classMonitoringSupported) { long sharedUnloaded = model.getSharedUnloaded(); long totalUnloaded = model.getTotalUnloaded(); long sharedClasses = model.getSharedLoaded() - sharedUnloaded; long totalClasses = model.getTotalLoaded() - totalUnloaded + sharedClasses; if (liveModel) chartSupport.addValues(model.getTimestamp(), new long[] { totalClasses, sharedClasses }); chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(totalClasses), chartSupport.formatDecimal(sharedClasses), chartSupport.formatDecimal(totalUnloaded), chartSupport.formatDecimal(sharedUnloaded) }); } } private void initModels(ApplicationMonitorModel model) { liveModel = model.isLive(); classMonitoringSupported = model.isClassMonitoringSupported(); SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.decimal(100, false, model.getChartCache()); chartDescriptor.addLineItems(TOTAL_LOADED_LEG, SHARED_LOADED_LEG); chartDescriptor.setDetailsItems(new String[] { TOTAL_LOADED, SHARED_LOADED, TOTAL_UNLOADED, SHARED_UNLOADED }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); model.registerClassesChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); } private void initComponents(ApplicationMonitorModel model) { setLayout(new BorderLayout()); setOpaque(false); if (model.isClassMonitoringSupported()) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN }); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } // --- Threads ------------------------------------------------------------- private static class ThreadsViewSupport extends JPanel { private static final String LIVE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Live_threads"); // NOI18N private static final String LIVE_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Live_threads_leg"); // NOI18N private static final String DAEMON = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Daemon_threads");// NOI18N private static final String DAEMON_LEG = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Daemon_threads_leg");// NOI18N private static final String PEAK = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Live_threads_peak"); // NOI18N private static final String STARTED = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Started_threads_total"); // NOI18N private boolean liveModel; private boolean threadsMonitoringSupported; private SimpleXYChartSupport chartSupport; public ThreadsViewSupport(ApplicationMonitorModel model) { initModels(model); initComponents(model); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Threads"), null, 10, this, null); // NOI18N } public void refresh(ApplicationMonitorModel model) { if (threadsMonitoringSupported) { long totalThreads = model.getTotalThreads(); long daemonThreads = model.getDeamonThreads(); long peakThreads = model.getPeakThreads(); long startedThreads = model.getStartedThreads(); if (liveModel) chartSupport.addValues(model.getTimestamp(), new long[] { totalThreads, daemonThreads }); chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(totalThreads), chartSupport.formatDecimal(daemonThreads), chartSupport.formatDecimal(peakThreads), chartSupport.formatDecimal(startedThreads) }); } } private void initModels(ApplicationMonitorModel model) { liveModel = model.isLive(); threadsMonitoringSupported = model.isThreadsMonitoringSupported(); SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.decimal(3, false, model.getChartCache()); chartDescriptor.addLineItems(LIVE_LEG, DAEMON_LEG); chartDescriptor.setDetailsItems(new String[] { LIVE, DAEMON, PEAK, STARTED }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); model.registerThreadsChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); } private void initComponents(ApplicationMonitorModel model) { setLayout(new BorderLayout()); setOpaque(false); if (model.isThreadsMonitoringSupported()) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN }); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } }