0
|
1 /*
|
|
2 * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
5 * This code is free software; you can redistribute it and/or modify it
|
|
6 * under the terms of the GNU General Public License version 2 only, as
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.ui;
|
|
26
|
|
27 import java.util.*;
|
|
28
|
|
29 import java.awt.*;
|
|
30 import java.awt.event.*;
|
|
31
|
|
32 import javax.swing.*;
|
|
33 import javax.swing.table.*;
|
|
34
|
|
35 import sun.jvm.hotspot.oops.ObjectHistogram;
|
|
36 import sun.jvm.hotspot.oops.ObjectHistogramElement;
|
|
37 import sun.jvm.hotspot.oops.Klass;
|
|
38
|
|
39 import sun.jvm.hotspot.ui.table.LongCellRenderer;
|
|
40 import sun.jvm.hotspot.ui.table.SortableTableModel;
|
|
41 import sun.jvm.hotspot.ui.table.SortHeaderCellRenderer;
|
|
42 import sun.jvm.hotspot.ui.table.SortHeaderMouseAdapter;
|
|
43 import sun.jvm.hotspot.ui.table.TableModelComparator;
|
|
44
|
|
45 import sun.jvm.hotspot.ui.action.*;
|
|
46
|
|
47 import com.sun.java.swing.ui.StatusBar;
|
|
48 import com.sun.java.swing.ui.CommonToolBar;
|
|
49
|
|
50 import com.sun.java.swing.action.ActionManager;
|
|
51 import com.sun.java.swing.action.DelegateAction;
|
|
52
|
|
53 /**
|
|
54 * Displays the results of an ObjectHistogram run in a JTable, with a
|
|
55 * button to display all objects of that type
|
|
56 */
|
|
57 public class ObjectHistogramPanel extends JPanel implements ActionListener {
|
|
58 private ObjectHistogramTableModel dataModel;
|
|
59 private ObjectHistogramToolBar toolbar;
|
|
60 private StatusBar statusBar;
|
|
61 private JTable table;
|
|
62 private java.util.List listeners;
|
|
63
|
|
64 public ObjectHistogramPanel(ObjectHistogram histo) {
|
|
65 dataModel = new ObjectHistogramTableModel(histo);
|
|
66 statusBar = new StatusBar();
|
|
67
|
|
68 table = new JTable(dataModel, new ObjectHistogramColummModel());
|
|
69 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
70 table.addMouseListener(new MouseAdapter() {
|
|
71 public void mouseClicked(MouseEvent evt) {
|
|
72 if (evt.getClickCount() == 2) {
|
|
73 fireShowObjectsOfType();
|
|
74 }
|
|
75 }
|
|
76 });
|
|
77
|
|
78 JTableHeader header = table.getTableHeader();
|
|
79 header.setDefaultRenderer(new SortHeaderCellRenderer(header, dataModel));
|
|
80 header.addMouseListener(new SortHeaderMouseAdapter(table, dataModel));
|
|
81
|
|
82 setLayout(new BorderLayout());
|
|
83
|
|
84 toolbar = new ObjectHistogramToolBar(statusBar);
|
|
85 add(toolbar, BorderLayout.NORTH);
|
|
86 add(new JScrollPane(table), BorderLayout.CENTER);
|
|
87 add(statusBar, BorderLayout.SOUTH);
|
|
88
|
|
89 registerActions();
|
|
90 }
|
|
91
|
|
92 private class ObjectHistogramToolBar extends CommonToolBar {
|
|
93
|
|
94 private JTextField searchTF;
|
|
95
|
|
96 public ObjectHistogramToolBar(StatusBar status) {
|
|
97 super(HSDBActionManager.getInstance(), status);
|
|
98 }
|
|
99
|
|
100 protected void addComponents() {
|
|
101 searchTF = new JTextField();
|
|
102 searchTF.setToolTipText("Find in Class Description");
|
|
103
|
|
104 // Pressing Enter on the text field will search
|
|
105 InputMap im = searchTF.getInputMap();
|
|
106 im.put(KeyStroke.getKeyStroke("ENTER"), "enterPressed");
|
|
107 ActionMap am = searchTF.getActionMap();
|
|
108 am.put("enterPressed", manager.getAction(FindAction.VALUE_COMMAND));
|
|
109
|
|
110 add(searchTF);
|
|
111 addButton(manager.getAction(FindAction.VALUE_COMMAND));
|
|
112 addButton(manager.getAction(ShowAction.VALUE_COMMAND));
|
|
113 }
|
|
114
|
|
115 public String getFindText() {
|
|
116 return searchTF.getText();
|
|
117 }
|
|
118 }
|
|
119
|
|
120 private class ObjectHistogramColummModel extends DefaultTableColumnModel {
|
|
121 private final String LABEL_SIZE = "Size";
|
|
122 private final String LABEL_COUNT = "Count";
|
|
123 private final String LABEL_DESC = "Class Description";
|
|
124
|
|
125
|
|
126 public ObjectHistogramColummModel() {
|
|
127 // Should actually get the line metrics for
|
|
128 int PREF_WIDTH = 80;
|
|
129 int MAX_WIDTH = 100;
|
|
130 int HUGE_WIDTH = 140;
|
|
131
|
|
132 LongCellRenderer lcRender = new LongCellRenderer();
|
|
133
|
|
134 TableColumn column;
|
|
135
|
|
136 // Size
|
|
137 column = new TableColumn(0, PREF_WIDTH);
|
|
138 column.setHeaderValue(LABEL_SIZE);
|
|
139 column.setMaxWidth(MAX_WIDTH);
|
|
140 column.setResizable(false);
|
|
141 column.setCellRenderer(lcRender);
|
|
142 addColumn(column);
|
|
143
|
|
144 // Count
|
|
145 column = new TableColumn(1, PREF_WIDTH);
|
|
146 column.setHeaderValue(LABEL_COUNT);
|
|
147 column.setMaxWidth(MAX_WIDTH);
|
|
148 column.setResizable(false);
|
|
149 column.setCellRenderer(lcRender);
|
|
150 addColumn(column);
|
|
151
|
|
152 // Description
|
|
153 column = new TableColumn(2, HUGE_WIDTH);
|
|
154 column.setHeaderValue(LABEL_DESC);
|
|
155 addColumn(column);
|
|
156 }
|
|
157 }
|
|
158
|
|
159
|
|
160 /**
|
|
161 * A table model which encapsulates the ObjectHistogram
|
|
162 */
|
|
163 private class ObjectHistogramTableModel extends SortableTableModel {
|
|
164 private String[] columnNames = { "Size", "Count", "Class Description" };
|
|
165 private Class[] columnClasses = { Long.class, Long.class, String.class };
|
|
166
|
|
167 public ObjectHistogramTableModel(ObjectHistogram histo) {
|
|
168 // Set the rows
|
|
169 elements = histo.getElements();
|
|
170 setComparator(new ObjectHistogramComparator(this));
|
|
171
|
|
172 }
|
|
173
|
|
174 public int getColumnCount() {
|
|
175 return columnNames.length;
|
|
176 }
|
|
177
|
|
178 public int getRowCount() {
|
|
179 return elements.size();
|
|
180 }
|
|
181
|
|
182 public String getColumnName(int col) {
|
|
183 return columnNames[col];
|
|
184 }
|
|
185
|
|
186 public Class getColumnClass(int col) {
|
|
187 return columnClasses[col];
|
|
188 }
|
|
189
|
|
190 public Object getValueAt(int row, int col) {
|
|
191 return getValueForColumn(getElement(row), col);
|
|
192 }
|
|
193
|
|
194 public Object getValueForColumn(Object obj, int col) {
|
|
195 ObjectHistogramElement el = (ObjectHistogramElement)obj;
|
|
196 switch (col) {
|
|
197 case 0:
|
|
198 return new Long(el.getSize());
|
|
199 case 1:
|
|
200 return new Long(el.getCount());
|
|
201 case 2:
|
|
202 return el.getDescription();
|
|
203 default:
|
|
204 throw new RuntimeException("Index (" + col + ") out of bounds");
|
|
205 }
|
|
206 }
|
|
207
|
|
208 public ObjectHistogramElement getElement(int index) {
|
|
209 return (ObjectHistogramElement) elements.get(index);
|
|
210 }
|
|
211
|
|
212 private class ObjectHistogramComparator extends TableModelComparator {
|
|
213
|
|
214 public ObjectHistogramComparator(ObjectHistogramTableModel model) {
|
|
215 super(model);
|
|
216 }
|
|
217
|
|
218 /**
|
|
219 * Returns the value for the comparing object for the
|
|
220 * column.
|
|
221 *
|
|
222 * @param obj Object that was passed for Comparator
|
|
223 * @param column the column to retrieve
|
|
224 */
|
|
225 public Object getValueForColumn(Object obj, int column) {
|
|
226 ObjectHistogramTableModel omodel = (ObjectHistogramTableModel)model;
|
|
227 return omodel.getValueForColumn(obj, column);
|
|
228 }
|
|
229 }
|
|
230
|
|
231 }
|
|
232
|
|
233
|
|
234 //
|
|
235 // ActionListener implementation and actions support
|
|
236 //
|
|
237
|
|
238 public void actionPerformed(ActionEvent evt) {
|
|
239 String command = evt.getActionCommand();
|
|
240
|
|
241 if (command.equals(ShowAction.VALUE_COMMAND)) {
|
|
242 fireShowObjectsOfType();
|
|
243 } else if (command.equals(FindAction.VALUE_COMMAND)) {
|
|
244 findObject();
|
|
245 }
|
|
246
|
|
247 }
|
|
248
|
|
249 protected void registerActions() {
|
|
250 registerAction(FindAction.VALUE_COMMAND);
|
|
251 registerAction(ShowAction.VALUE_COMMAND);
|
|
252 }
|
|
253
|
|
254 private void registerAction(String actionName) {
|
|
255 ActionManager manager = ActionManager.getInstance();
|
|
256 DelegateAction action = manager.getDelegateAction(actionName);
|
|
257 action.addActionListener(this);
|
|
258 }
|
|
259
|
|
260 public interface Listener {
|
|
261 public void showObjectsOfType(Klass type);
|
|
262 }
|
|
263
|
|
264 public void addPanelListener(Listener listener) {
|
|
265 if (listeners == null) {
|
|
266 listeners = new ArrayList();
|
|
267 }
|
|
268 listeners.add(listener);
|
|
269 }
|
|
270
|
|
271 public void removePanelListener(Listener listener) {
|
|
272 if (listeners != null) {
|
|
273 listeners.remove(listener);
|
|
274 }
|
|
275 }
|
|
276
|
|
277 //--------------------------------------------------------------------------------
|
|
278 // Internals only below this point
|
|
279 //
|
|
280
|
|
281 /**
|
|
282 * Find and select the row that contains the text in the find field starting
|
|
283 * from the current selected row.
|
|
284 *
|
|
285 * Uses a linear search from the current row. Could be optimized withing the
|
|
286 * model and internal representation.
|
|
287 */
|
|
288 private void findObject() {
|
|
289 String findText = toolbar.getFindText();
|
|
290
|
|
291 if (findText == null || findText.equals("")) {
|
|
292 return;
|
|
293 }
|
|
294
|
|
295 TableModel model = table.getModel();
|
|
296
|
|
297 int row = table.getSelectedRow();
|
|
298 if (row == model.getRowCount()) {
|
|
299 row = 0;
|
|
300 } else {
|
|
301 // Start at the row after the selected row.
|
|
302 row++;
|
|
303 }
|
|
304
|
|
305 String value;
|
|
306 for (int i = row; i < model.getRowCount(); i++) {
|
|
307 value = (String)model.getValueAt(i, 2);
|
|
308 if (value != null && value.startsWith(findText)) {
|
|
309 table.setRowSelectionInterval(i, i);
|
|
310 Rectangle cellBounds = table.getCellRect(i, 0, true);
|
|
311 table.scrollRectToVisible(cellBounds);
|
|
312 return;
|
|
313 }
|
|
314 }
|
|
315
|
|
316 // Wrap the table to search in the top rows.
|
|
317 for (int i = 0; i < row; i++) {
|
|
318 value = (String)model.getValueAt(i, 2);
|
|
319 if (value != null && value.startsWith(findText)) {
|
|
320 table.setRowSelectionInterval(i, i);
|
|
321 Rectangle cellBounds = table.getCellRect(i, 0, true);
|
|
322 table.scrollRectToVisible(cellBounds);
|
|
323 return;
|
|
324 }
|
|
325 }
|
|
326 }
|
|
327
|
|
328 private void fireShowObjectsOfType() {
|
|
329 int i = table.getSelectedRow();
|
|
330 if (i < 0) {
|
|
331 return;
|
|
332 }
|
|
333
|
|
334 ObjectHistogramElement el = dataModel.getElement(i);
|
|
335
|
|
336 for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
|
|
337 Listener listener = (Listener) iter.next();
|
|
338 listener.showObjectsOfType(el.getKlass());
|
|
339 }
|
|
340 }
|
|
341
|
|
342 public static void main(String[] args) {
|
|
343
|
|
344 }
|
|
345 }
|