Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/ObjectHistogramPanel.java
41161 views
/*1* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.ui;2526import java.util.*;2728import java.awt.*;29import java.awt.event.*;3031import javax.swing.*;32import javax.swing.table.*;3334import sun.jvm.hotspot.oops.ObjectHistogram;35import sun.jvm.hotspot.oops.ObjectHistogramElement;36import sun.jvm.hotspot.oops.Klass;3738import sun.jvm.hotspot.ui.table.LongCellRenderer;39import sun.jvm.hotspot.ui.table.SortableTableModel;40import sun.jvm.hotspot.ui.table.SortHeaderCellRenderer;41import sun.jvm.hotspot.ui.table.SortHeaderMouseAdapter;42import sun.jvm.hotspot.ui.table.TableModelComparator;4344import sun.jvm.hotspot.ui.action.*;4546import com.sun.java.swing.ui.StatusBar;47import com.sun.java.swing.ui.CommonToolBar;4849import com.sun.java.swing.action.ActionManager;50import com.sun.java.swing.action.DelegateAction;5152/**53* Displays the results of an ObjectHistogram run in a JTable, with a54* button to display all objects of that type55*/56public class ObjectHistogramPanel extends JPanel implements ActionListener {57private ObjectHistogramTableModel dataModel;58private ObjectHistogramToolBar toolbar;59private StatusBar statusBar;60private JTable table;61private java.util.List<Listener> listeners;6263public ObjectHistogramPanel(ObjectHistogram histo) {64dataModel = new ObjectHistogramTableModel(histo);65statusBar = new StatusBar();6667table = new JTable(dataModel, new ObjectHistogramColummModel());68table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);69table.addMouseListener(new MouseAdapter() {70public void mouseClicked(MouseEvent evt) {71if (evt.getClickCount() == 2) {72fireShowObjectsOfType();73}74}75});7677JTableHeader header = table.getTableHeader();78header.setDefaultRenderer(new SortHeaderCellRenderer(header, dataModel));79header.addMouseListener(new SortHeaderMouseAdapter(table, dataModel));8081setLayout(new BorderLayout());8283toolbar = new ObjectHistogramToolBar(statusBar);84add(toolbar, BorderLayout.NORTH);85add(new JScrollPane(table), BorderLayout.CENTER);86add(statusBar, BorderLayout.SOUTH);8788registerActions();89}9091private class ObjectHistogramToolBar extends CommonToolBar {9293private JTextField searchTF;9495public ObjectHistogramToolBar(StatusBar status) {96super(HSDBActionManager.getInstance(), status);97}9899protected void addComponents() {100searchTF = new JTextField();101searchTF.setToolTipText("Find in Class Description");102103// Pressing Enter on the text field will search104InputMap im = searchTF.getInputMap();105im.put(KeyStroke.getKeyStroke("ENTER"), "enterPressed");106ActionMap am = searchTF.getActionMap();107am.put("enterPressed", manager.getAction(FindAction.VALUE_COMMAND));108109add(searchTF);110addButton(manager.getAction(FindAction.VALUE_COMMAND));111addButton(manager.getAction(ShowAction.VALUE_COMMAND));112}113114public String getFindText() {115return searchTF.getText();116}117}118119private class ObjectHistogramColummModel extends DefaultTableColumnModel {120private final String LABEL_SIZE = "Size";121private final String LABEL_COUNT = "Count";122private final String LABEL_DESC = "Class Description";123124125public ObjectHistogramColummModel() {126// Should actually get the line metrics for127int PREF_WIDTH = 80;128int MAX_WIDTH = 100;129int HUGE_WIDTH = 140;130131LongCellRenderer lcRender = new LongCellRenderer();132133TableColumn column;134135// Size136column = new TableColumn(0, PREF_WIDTH);137column.setHeaderValue(LABEL_SIZE);138column.setMaxWidth(MAX_WIDTH);139column.setResizable(false);140column.setCellRenderer(lcRender);141addColumn(column);142143// Count144column = new TableColumn(1, PREF_WIDTH);145column.setHeaderValue(LABEL_COUNT);146column.setMaxWidth(MAX_WIDTH);147column.setResizable(false);148column.setCellRenderer(lcRender);149addColumn(column);150151// Description152column = new TableColumn(2, HUGE_WIDTH);153column.setHeaderValue(LABEL_DESC);154addColumn(column);155}156}157158159/**160* A table model which encapsulates the ObjectHistogram161*/162private class ObjectHistogramTableModel extends SortableTableModel<ObjectHistogramElement> {163private String[] columnNames = { "Size", "Count", "Class Description" };164private Class[] columnClasses = { Long.class, Long.class, String.class };165166public ObjectHistogramTableModel(ObjectHistogram histo) {167// Set the rows168elements = histo.getElements();169setComparator(new ObjectHistogramComparator(this));170171}172173public int getColumnCount() {174return columnNames.length;175}176177public int getRowCount() {178return elements.size();179}180181public String getColumnName(int col) {182return columnNames[col];183}184185public Class getColumnClass(int col) {186return columnClasses[col];187}188189public Object getValueAt(int row, int col) {190return getValueForColumn(getElement(row), col);191}192193public Comparable<?> getValueForColumn(Object obj, int col) {194ObjectHistogramElement el = (ObjectHistogramElement)obj;195switch (col) {196case 0:197return el.getSize();198case 1:199return el.getCount();200case 2:201return el.getDescription();202default:203throw new RuntimeException("Index (" + col + ") out of bounds");204}205}206207public ObjectHistogramElement getElement(int index) {208return elements.get(index);209}210211private class ObjectHistogramComparator extends TableModelComparator {212213public ObjectHistogramComparator(ObjectHistogramTableModel model) {214super(model);215}216217/**218* Returns the value for the comparing object for the219* column.220*221* @param obj Object that was passed for Comparator222* @param column the column to retrieve223*/224public Comparable<?> getValueForColumn(Object obj, int column) {225ObjectHistogramTableModel omodel = (ObjectHistogramTableModel)model;226return omodel.getValueForColumn(obj, column);227}228}229230}231232233//234// ActionListener implementation and actions support235//236237public void actionPerformed(ActionEvent evt) {238String command = evt.getActionCommand();239240if (command.equals(ShowAction.VALUE_COMMAND)) {241fireShowObjectsOfType();242} else if (command.equals(FindAction.VALUE_COMMAND)) {243findObject();244}245246}247248protected void registerActions() {249registerAction(FindAction.VALUE_COMMAND);250registerAction(ShowAction.VALUE_COMMAND);251}252253private void registerAction(String actionName) {254ActionManager manager = ActionManager.getInstance();255DelegateAction action = manager.getDelegateAction(actionName);256action.addActionListener(this);257}258259public interface Listener {260public void showObjectsOfType(Klass type);261}262263public void addPanelListener(Listener listener) {264if (listeners == null) {265listeners = new ArrayList<>();266}267listeners.add(listener);268}269270public void removePanelListener(Listener listener) {271if (listeners != null) {272listeners.remove(listener);273}274}275276//--------------------------------------------------------------------------------277// Internals only below this point278//279280/**281* Find and select the row that contains the text in the find field starting282* from the current selected row.283*284* Uses a linear search from the current row. Could be optimized withing the285* model and internal representation.286*/287private void findObject() {288String findText = toolbar.getFindText();289290if (findText == null || findText.equals("")) {291return;292}293294TableModel model = table.getModel();295296int row = table.getSelectedRow();297if (row == model.getRowCount()) {298row = 0;299} else {300// Start at the row after the selected row.301row++;302}303304String value;305for (int i = row; i < model.getRowCount(); i++) {306value = (String)model.getValueAt(i, 2);307if (value != null && value.startsWith(findText)) {308table.setRowSelectionInterval(i, i);309Rectangle cellBounds = table.getCellRect(i, 0, true);310table.scrollRectToVisible(cellBounds);311return;312}313}314315// Wrap the table to search in the top rows.316for (int i = 0; i < row; i++) {317value = (String)model.getValueAt(i, 2);318if (value != null && value.startsWith(findText)) {319table.setRowSelectionInterval(i, i);320Rectangle cellBounds = table.getCellRect(i, 0, true);321table.scrollRectToVisible(cellBounds);322return;323}324}325}326327private void fireShowObjectsOfType() {328int i = table.getSelectedRow();329if (i < 0) {330return;331}332333ObjectHistogramElement el = dataModel.getElement(i);334335for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {336Listener listener = (Listener) iter.next();337listener.showObjectsOfType(el.getKlass());338}339}340341public static void main(String[] args) {342343}344}345346347