| /* |
| * Copyright (c) 2000, 2002, 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. |
| * |
| * 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.jvm.hotspot.ui; |
| |
| import java.util.*; |
| |
| import java.awt.*; |
| import java.awt.event.*; |
| |
| import javax.swing.*; |
| import javax.swing.table.*; |
| |
| import sun.jvm.hotspot.oops.ObjectHistogram; |
| import sun.jvm.hotspot.oops.ObjectHistogramElement; |
| import sun.jvm.hotspot.oops.Klass; |
| |
| import sun.jvm.hotspot.ui.table.LongCellRenderer; |
| import sun.jvm.hotspot.ui.table.SortableTableModel; |
| import sun.jvm.hotspot.ui.table.SortHeaderCellRenderer; |
| import sun.jvm.hotspot.ui.table.SortHeaderMouseAdapter; |
| import sun.jvm.hotspot.ui.table.TableModelComparator; |
| |
| import sun.jvm.hotspot.ui.action.*; |
| |
| import com.sun.java.swing.ui.StatusBar; |
| import com.sun.java.swing.ui.CommonToolBar; |
| |
| import com.sun.java.swing.action.ActionManager; |
| import com.sun.java.swing.action.DelegateAction; |
| |
| /** |
| * Displays the results of an ObjectHistogram run in a JTable, with a |
| * button to display all objects of that type |
| */ |
| public class ObjectHistogramPanel extends JPanel implements ActionListener { |
| private ObjectHistogramTableModel dataModel; |
| private ObjectHistogramToolBar toolbar; |
| private StatusBar statusBar; |
| private JTable table; |
| private java.util.List listeners; |
| |
| public ObjectHistogramPanel(ObjectHistogram histo) { |
| dataModel = new ObjectHistogramTableModel(histo); |
| statusBar = new StatusBar(); |
| |
| table = new JTable(dataModel, new ObjectHistogramColummModel()); |
| table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
| table.addMouseListener(new MouseAdapter() { |
| public void mouseClicked(MouseEvent evt) { |
| if (evt.getClickCount() == 2) { |
| fireShowObjectsOfType(); |
| } |
| } |
| }); |
| |
| JTableHeader header = table.getTableHeader(); |
| header.setDefaultRenderer(new SortHeaderCellRenderer(header, dataModel)); |
| header.addMouseListener(new SortHeaderMouseAdapter(table, dataModel)); |
| |
| setLayout(new BorderLayout()); |
| |
| toolbar = new ObjectHistogramToolBar(statusBar); |
| add(toolbar, BorderLayout.NORTH); |
| add(new JScrollPane(table), BorderLayout.CENTER); |
| add(statusBar, BorderLayout.SOUTH); |
| |
| registerActions(); |
| } |
| |
| private class ObjectHistogramToolBar extends CommonToolBar { |
| |
| private JTextField searchTF; |
| |
| public ObjectHistogramToolBar(StatusBar status) { |
| super(HSDBActionManager.getInstance(), status); |
| } |
| |
| protected void addComponents() { |
| searchTF = new JTextField(); |
| searchTF.setToolTipText("Find in Class Description"); |
| |
| // Pressing Enter on the text field will search |
| InputMap im = searchTF.getInputMap(); |
| im.put(KeyStroke.getKeyStroke("ENTER"), "enterPressed"); |
| ActionMap am = searchTF.getActionMap(); |
| am.put("enterPressed", manager.getAction(FindAction.VALUE_COMMAND)); |
| |
| add(searchTF); |
| addButton(manager.getAction(FindAction.VALUE_COMMAND)); |
| addButton(manager.getAction(ShowAction.VALUE_COMMAND)); |
| } |
| |
| public String getFindText() { |
| return searchTF.getText(); |
| } |
| } |
| |
| private class ObjectHistogramColummModel extends DefaultTableColumnModel { |
| private final String LABEL_SIZE = "Size"; |
| private final String LABEL_COUNT = "Count"; |
| private final String LABEL_DESC = "Class Description"; |
| |
| |
| public ObjectHistogramColummModel() { |
| // Should actually get the line metrics for |
| int PREF_WIDTH = 80; |
| int MAX_WIDTH = 100; |
| int HUGE_WIDTH = 140; |
| |
| LongCellRenderer lcRender = new LongCellRenderer(); |
| |
| TableColumn column; |
| |
| // Size |
| column = new TableColumn(0, PREF_WIDTH); |
| column.setHeaderValue(LABEL_SIZE); |
| column.setMaxWidth(MAX_WIDTH); |
| column.setResizable(false); |
| column.setCellRenderer(lcRender); |
| addColumn(column); |
| |
| // Count |
| column = new TableColumn(1, PREF_WIDTH); |
| column.setHeaderValue(LABEL_COUNT); |
| column.setMaxWidth(MAX_WIDTH); |
| column.setResizable(false); |
| column.setCellRenderer(lcRender); |
| addColumn(column); |
| |
| // Description |
| column = new TableColumn(2, HUGE_WIDTH); |
| column.setHeaderValue(LABEL_DESC); |
| addColumn(column); |
| } |
| } |
| |
| |
| /** |
| * A table model which encapsulates the ObjectHistogram |
| */ |
| private class ObjectHistogramTableModel extends SortableTableModel { |
| private String[] columnNames = { "Size", "Count", "Class Description" }; |
| private Class[] columnClasses = { Long.class, Long.class, String.class }; |
| |
| public ObjectHistogramTableModel(ObjectHistogram histo) { |
| // Set the rows |
| elements = histo.getElements(); |
| setComparator(new ObjectHistogramComparator(this)); |
| |
| } |
| |
| public int getColumnCount() { |
| return columnNames.length; |
| } |
| |
| public int getRowCount() { |
| return elements.size(); |
| } |
| |
| public String getColumnName(int col) { |
| return columnNames[col]; |
| } |
| |
| public Class getColumnClass(int col) { |
| return columnClasses[col]; |
| } |
| |
| public Object getValueAt(int row, int col) { |
| return getValueForColumn(getElement(row), col); |
| } |
| |
| public Object getValueForColumn(Object obj, int col) { |
| ObjectHistogramElement el = (ObjectHistogramElement)obj; |
| switch (col) { |
| case 0: |
| return new Long(el.getSize()); |
| case 1: |
| return new Long(el.getCount()); |
| case 2: |
| return el.getDescription(); |
| default: |
| throw new RuntimeException("Index (" + col + ") out of bounds"); |
| } |
| } |
| |
| public ObjectHistogramElement getElement(int index) { |
| return (ObjectHistogramElement) elements.get(index); |
| } |
| |
| private class ObjectHistogramComparator extends TableModelComparator { |
| |
| public ObjectHistogramComparator(ObjectHistogramTableModel model) { |
| super(model); |
| } |
| |
| /** |
| * Returns the value for the comparing object for the |
| * column. |
| * |
| * @param obj Object that was passed for Comparator |
| * @param column the column to retrieve |
| */ |
| public Object getValueForColumn(Object obj, int column) { |
| ObjectHistogramTableModel omodel = (ObjectHistogramTableModel)model; |
| return omodel.getValueForColumn(obj, column); |
| } |
| } |
| |
| } |
| |
| |
| // |
| // ActionListener implementation and actions support |
| // |
| |
| public void actionPerformed(ActionEvent evt) { |
| String command = evt.getActionCommand(); |
| |
| if (command.equals(ShowAction.VALUE_COMMAND)) { |
| fireShowObjectsOfType(); |
| } else if (command.equals(FindAction.VALUE_COMMAND)) { |
| findObject(); |
| } |
| |
| } |
| |
| protected void registerActions() { |
| registerAction(FindAction.VALUE_COMMAND); |
| registerAction(ShowAction.VALUE_COMMAND); |
| } |
| |
| private void registerAction(String actionName) { |
| ActionManager manager = ActionManager.getInstance(); |
| DelegateAction action = manager.getDelegateAction(actionName); |
| action.addActionListener(this); |
| } |
| |
| public interface Listener { |
| public void showObjectsOfType(Klass type); |
| } |
| |
| public void addPanelListener(Listener listener) { |
| if (listeners == null) { |
| listeners = new ArrayList(); |
| } |
| listeners.add(listener); |
| } |
| |
| public void removePanelListener(Listener listener) { |
| if (listeners != null) { |
| listeners.remove(listener); |
| } |
| } |
| |
| //-------------------------------------------------------------------------------- |
| // Internals only below this point |
| // |
| |
| /** |
| * Find and select the row that contains the text in the find field starting |
| * from the current selected row. |
| * |
| * Uses a linear search from the current row. Could be optimized withing the |
| * model and internal representation. |
| */ |
| private void findObject() { |
| String findText = toolbar.getFindText(); |
| |
| if (findText == null || findText.equals("")) { |
| return; |
| } |
| |
| TableModel model = table.getModel(); |
| |
| int row = table.getSelectedRow(); |
| if (row == model.getRowCount()) { |
| row = 0; |
| } else { |
| // Start at the row after the selected row. |
| row++; |
| } |
| |
| String value; |
| for (int i = row; i < model.getRowCount(); i++) { |
| value = (String)model.getValueAt(i, 2); |
| if (value != null && value.startsWith(findText)) { |
| table.setRowSelectionInterval(i, i); |
| Rectangle cellBounds = table.getCellRect(i, 0, true); |
| table.scrollRectToVisible(cellBounds); |
| return; |
| } |
| } |
| |
| // Wrap the table to search in the top rows. |
| for (int i = 0; i < row; i++) { |
| value = (String)model.getValueAt(i, 2); |
| if (value != null && value.startsWith(findText)) { |
| table.setRowSelectionInterval(i, i); |
| Rectangle cellBounds = table.getCellRect(i, 0, true); |
| table.scrollRectToVisible(cellBounds); |
| return; |
| } |
| } |
| } |
| |
| private void fireShowObjectsOfType() { |
| int i = table.getSelectedRow(); |
| if (i < 0) { |
| return; |
| } |
| |
| ObjectHistogramElement el = dataModel.getElement(i); |
| |
| for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { |
| Listener listener = (Listener) iter.next(); |
| listener.showObjectsOfType(el.getKlass()); |
| } |
| } |
| |
| public static void main(String[] args) { |
| |
| } |
| } |