001: package com.tagtraum.perf.gcviewer;
002:
003: import com.tagtraum.perf.gcviewer.action.*;
004: import com.tagtraum.perf.gcviewer.renderer.*;
005: import com.tagtraum.perf.gcviewer.util.NumberParser;
006:
007: import javax.swing.*;
008: import javax.swing.event.InternalFrameEvent;
009: import javax.swing.event.InternalFrameListener;
010: import java.awt.*;
011: import java.awt.event.ActionEvent;
012: import java.awt.event.ActionListener;
013: import java.awt.event.WindowAdapter;
014: import java.awt.event.WindowEvent;
015: import java.awt.image.BufferedImage;
016: import java.beans.PropertyChangeEvent;
017: import java.beans.PropertyChangeListener;
018: import java.beans.PropertyVetoException;
019: import java.io.*;
020: import java.util.*;
021: import java.net.URL;
022: import java.net.MalformedURLException;
023:
024: /**
025: * Main class.
026: *
027: * Date: Jan 30, 2002
028: * Time: 4:59:49 PM
029: * @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
030: * @version $Id: $
031: */
032: public class GCViewer extends JFrame {
033:
034: public static ResourceBundle localStrings = ResourceBundle
035: .getBundle("com.tagtraum.perf.gcviewer.localStrings");
036: private static final String PREFERENCE_VERSION = "1.1";
037: private static final String FULL_GC_LINES = "fullgclines";
038: private static final String INC_GC_LINES = "incgclines";
039: private static final String GC_LINES_LINE = "gctimesline";
040: private static final String GC_TIMES_RECTANGLES = "gctimesrectangles";
041: private static final String TOTAL_MEMORY = "totalmemory";
042: private static final String USED_MEMORY = "usedmemory";
043: private static final String TENURED_MEMORY = "tenuredmemory";
044: private static final String YOUNG_MEMORY = "youngmemory";
045:
046: private JToolBar toolBar;
047: private ActionListener viewActionListener;
048: private JMenu fileMenu;
049: private JMenu windowMenu;
050: private JMenuItem exportMenuItem;
051: private ButtonGroup windowCheckBoxGroup = new ButtonGroup();
052: private JDesktopPane desktopPane;
053: private JComboBox zoomComboBox;
054: // actions
055: private Exit exitAction = new Exit(this );
056: private About aboutAction = new About(this );
057: private OpenFile openFileAction = new OpenFile(this );
058: private OpenURL openURLAction = new OpenURL(this );
059: //private AddFile addFileAction = new AddFile(this);
060: private Refresh refreshAction = new Refresh(this );
061: private Export exportAction = new Export(this );
062: private Zoom zoomAction = new Zoom(this );
063: private Arrange arrangeAction = new Arrange(this );
064: private Watch watchAction = new Watch(this );
065: private JCheckBoxMenuItem showDataPanel;
066: private JCheckBoxMenuItem fullGCLines;
067: private JCheckBoxMenuItem incGCLines;
068: private JCheckBoxMenuItem gcTimesLine;
069: private JCheckBoxMenuItem gcTimesRectangle;
070: private JCheckBoxMenuItem usedMemory;
071: private JCheckBoxMenuItem totalMemory;
072: private JCheckBoxMenuItem tenuredMemory;
073: private JCheckBoxMenuItem youngMemory;
074: private JCheckBoxMenuItem watchCheckBoxMenuItem;
075: private JCheckBoxMenuItem antiAlias;
076: private Map lines;
077: private JToggleButton watchToggle;
078:
079: private RecentURLsMenu recentURLsMenu;
080:
081: public GCViewer() {
082: super ("tagtraum industries incorporated - GCViewer");
083: setIconImage(Toolkit.getDefaultToolkit().getImage(
084: getClass().getResource("gcviewericon.gif")));
085: desktopPane = new DesktopPane(this );
086: addWindowListener(new WindowAdapter() {
087: public void windowClosing(final WindowEvent e) {
088: exit();
089: }
090: });
091: viewActionListener = new ViewMenuActionListener();
092: recentURLsMenu = new RecentURLsMenu(this );
093: openURLAction.setRecentURLsModel(recentURLsMenu
094: .getRecentURLsModel());
095:
096: setJMenuBar(initMenuBar());
097: toolBar = initToolBar();
098:
099: // cross reference the two toggle buttons
100: watchCheckBoxMenuItem.addActionListener(new ActionListener() {
101: public void actionPerformed(final ActionEvent e) {
102: watchToggle.setSelected(watchCheckBoxMenuItem
103: .getState());
104: }
105: });
106: watchToggle.addActionListener(new ActionListener() {
107: public void actionPerformed(final ActionEvent e) {
108: watchCheckBoxMenuItem
109: .setState(watchToggle.isSelected());
110: }
111: });
112:
113: getContentPane().add(toolBar, BorderLayout.NORTH);
114: getContentPane().add(desktopPane, BorderLayout.CENTER);
115:
116: loadPreferences();
117: setVisible(true);
118: }
119:
120: public RecentURLsMenu getRecentFilesMenu() {
121: return recentURLsMenu;
122: }
123:
124: public JDesktopPane getDesktopPane() {
125: return desktopPane;
126: }
127:
128: private InternalFrameListener gcDocumentListener = new InternalFrameListener() {
129: public void internalFrameOpened(final InternalFrameEvent e) {
130: final JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(
131: new WindowMenuItemAction(e));
132: windowMenu.add(menuItem);
133: windowCheckBoxGroup.add(menuItem);
134: }
135:
136: public void internalFrameClosing(final InternalFrameEvent e) {
137: }
138:
139: public void internalFrameClosed(final InternalFrameEvent e) {
140: if (desktopPane.getAllFrames().length == 0)
141: arrangeAction.setEnabled(false);
142: ((GCDocument) e.getInternalFrame()).getRefreshWatchDog()
143: .stop();
144: // remove menuitem from menu and from button group
145: for (int i = 2; i < windowMenu.getItemCount(); i++) {
146: final JMenuItem item = windowMenu.getItem(i);
147: if (((WindowMenuItemAction) item.getAction())
148: .getGcDocument() == e.getInternalFrame()) {
149: windowMenu.remove(item);
150: windowCheckBoxGroup.remove(item);
151: break;
152: }
153: }
154: }
155:
156: public void internalFrameIconified(final InternalFrameEvent e) {
157: }
158:
159: public void internalFrameDeiconified(final InternalFrameEvent e) {
160: }
161:
162: public void internalFrameActivated(final InternalFrameEvent e) {
163: for (int i = 2; i < windowMenu.getItemCount(); i++) {
164: final JMenuItem item = windowMenu.getItem(i);
165: if (((WindowMenuItemAction) item.getAction())
166: .getGcDocument() == e.getInternalFrame()) {
167: item.setSelected(true);
168: break;
169: }
170: }
171: zoomComboBox.setSelectedItem((int) (getSelectedGCDocument()
172: .getModelChart().getScaleFactor() * 1000.0)
173: + "%");
174: exportAction.setEnabled(true);
175: refreshAction.setEnabled(true);
176: watchAction.setEnabled(true);
177: watchCheckBoxMenuItem.setSelected(getSelectedGCDocument()
178: .isWatched());
179: getSelectedGCDocument().getRefreshWatchDog().setAction(
180: watchAction);
181: watchToggle
182: .setSelected(getSelectedGCDocument().isWatched());
183: //addFileAction.setEnabled(true);
184: zoomAction.setEnabled(true);
185: arrangeAction.setEnabled(true);
186: fullGCLines.setState(getSelectedGCDocument()
187: .getModelChart().isShowFullGCLines());
188: incGCLines.setState(getSelectedGCDocument().getModelChart()
189: .isShowIncGCLines());
190: gcTimesLine.setState(getSelectedGCDocument()
191: .getModelChart().isShowGCTimesLine());
192: gcTimesRectangle.setState(getSelectedGCDocument()
193: .getModelChart().isShowGCTimesRectangles());
194: totalMemory.setState(getSelectedGCDocument()
195: .getModelChart().isShowTotalMemoryLine());
196: usedMemory.setState(getSelectedGCDocument().getModelChart()
197: .isShowUsedMemoryLine());
198: tenuredMemory.setState(getSelectedGCDocument()
199: .getModelChart().isShowTenured());
200: youngMemory.setState(getSelectedGCDocument()
201: .getModelChart().isShowYoung());
202: showDataPanel.setState(getSelectedGCDocument()
203: .isShowModelPanel());
204: antiAlias.setSelected(getSelectedGCDocument()
205: .getModelChart().isAntiAlias());
206: }
207:
208: public void internalFrameDeactivated(final InternalFrameEvent e) {
209: exportAction.setEnabled(false);
210: refreshAction.setEnabled(false);
211: watchAction.setEnabled(false);
212: //addFileAction.setEnabled(false);
213: zoomAction.setEnabled(false);
214: watchToggle.setSelected(false);
215: watchCheckBoxMenuItem.setSelected(false);
216: ((GCDocument) e.getInternalFrame()).getRefreshWatchDog()
217: .setAction(null);
218: }
219: };
220:
221: public GCDocument getSelectedGCDocument() {
222: return (GCDocument) desktopPane.getSelectedFrame();
223: }
224:
225: private static URL[] convertFilesToURLs(final File[] files)
226: throws MalformedURLException {
227: final URL[] urls = new URL[files.length];
228: for (int i = 0; i < files.length; i++) {
229: urls[i] = files[i].getAbsoluteFile().toURL();
230: }
231: return urls;
232: }
233:
234: public void open(final File[] files) {
235: // delegate to open(...)
236: try {
237: final URL[] urls = convertFilesToURLs(files);
238: if (files.length >= 1) {
239: //addFileAction.setSelectedFile(files[0]);
240: }
241: open(urls);
242: } catch (RuntimeException e) {
243: e.printStackTrace();
244: JOptionPane.showMessageDialog(GCViewer.this , e.toString()
245: + " " + e.getLocalizedMessage(), localStrings
246: .getString("fileopen_dialog_read_file_failed"),
247: JOptionPane.ERROR_MESSAGE);
248: } catch (Exception e) {
249: //e.printStackTrace();
250: JOptionPane.showMessageDialog(GCViewer.this , e
251: .getLocalizedMessage(), localStrings
252: .getString("fileopen_dialog_read_file_failed"),
253: JOptionPane.ERROR_MESSAGE);
254: }
255: }
256:
257: public void open(final URL[] urls) {
258: try {
259: if (urls.length >= 1) {
260: final URL url = urls[0];
261: final GCDocument gcDocument = new GCDocument(this , url
262: .toString());
263: gcDocument.add(url);
264: gcDocument.addInternalFrameListener(gcDocumentListener);
265: desktopPane.add(gcDocument);
266: gcDocument.setSelected(true);
267: gcDocument.setSize(450, 300);
268: gcDocument.setMaximum(true);
269: //addAction.setSelectedFile(url);
270: gcDocument.setVisible(true);
271: }
272: if (urls.length > 1) {
273: final URL[] addURLs = new URL[urls.length - 1];
274: System.arraycopy(urls, 1, addURLs, 0, addURLs.length);
275: add(addURLs);
276: }
277: recentURLsMenu.getRecentURLsModel().add(urls);
278: repaint();
279: } catch (RuntimeException e) {
280: e.printStackTrace();
281: JOptionPane.showMessageDialog(GCViewer.this , e.toString()
282: + " " + e.getLocalizedMessage(), localStrings
283: .getString("fileopen_dialog_read_file_failed"),
284: JOptionPane.ERROR_MESSAGE);
285: } catch (Exception e) {
286: //e.printStackTrace();
287: JOptionPane.showMessageDialog(GCViewer.this , e
288: .getLocalizedMessage(), localStrings
289: .getString("fileopen_dialog_read_file_failed"),
290: JOptionPane.ERROR_MESSAGE);
291: }
292: }
293:
294: public void add(final File[] files) {
295: try {
296: if (files.length >= 0)
297: openFileAction.setSelectedFile(files[0]);
298: final URL[] urls = convertFilesToURLs(files);
299: add(urls);
300: } catch (RuntimeException e) {
301: e.printStackTrace();
302: JOptionPane.showMessageDialog(GCViewer.this , e.toString()
303: + " " + e.getLocalizedMessage(), localStrings
304: .getString("fileopen_dialog_read_file_failed"),
305: JOptionPane.ERROR_MESSAGE);
306: } catch (Exception e) {
307: //e.printStackTrace();
308: JOptionPane.showMessageDialog(GCViewer.this , e
309: .getLocalizedMessage(), localStrings
310: .getString("fileopen_dialog_read_file_failed"),
311: JOptionPane.ERROR_MESSAGE);
312: }
313: }
314:
315: public void add(final URL[] urls) {
316: try {
317: for (int i = 0; i < urls.length; i++) {
318: final URL url = urls[i];
319: getSelectedGCDocument().add(url);
320: }
321: recentURLsMenu.getRecentURLsModel().add(urls);
322: repaint();
323: } catch (RuntimeException e) {
324: e.printStackTrace();
325: JOptionPane.showMessageDialog(GCViewer.this , e.toString()
326: + " " + e.getLocalizedMessage(), localStrings
327: .getString("fileopen_dialog_read_file_failed"),
328: JOptionPane.ERROR_MESSAGE);
329: } catch (Exception e) {
330: //e.printStackTrace();
331: JOptionPane.showMessageDialog(GCViewer.this , e
332: .getLocalizedMessage(), localStrings
333: .getString("fileopen_dialog_read_file_failed"),
334: JOptionPane.ERROR_MESSAGE);
335: }
336: }
337:
338: private JToolBar initToolBar() {
339: final JToolBar toolBar = new JToolBar();
340: toolBar.setFloatable(false);
341: toolBar.add(openFileAction);
342: toolBar.add(openURLAction);
343: //toolBar.add(addFileAction);
344: toolBar.add(exportAction);
345: toolBar.add(refreshAction);
346: watchToggle = new JToggleButton();
347: watchToggle.setAction(watchAction);
348: watchToggle.setText("");
349: toolBar.add(watchToggle);
350: toolBar.addSeparator();
351: zoomComboBox = new JComboBox(
352: new String[] { "1%", "5%", "10%", "50%", "100%",
353: "200%", "300%", "500%", "1000%", "5000%" });
354: zoomComboBox.setSelectedIndex(2);
355: zoomComboBox.setAction(zoomAction);
356: zoomComboBox.setEditable(true);
357: zoomComboBox.setMaximumSize(zoomComboBox.getPreferredSize());
358: toolBar.add(zoomComboBox);
359: toolBar.addSeparator();
360: toolBar.add(aboutAction);
361: return toolBar;
362: }
363:
364: /**
365: * Creates the horizontal rectangle used in the menus.
366: *
367: * @param paint paint of the rectangle
368: * @param width
369: * @param height
370: * @return icon
371: */
372: private static ImageIcon createMonoColoredImageIcon(
373: final Paint paint, final int width, final int height) {
374: final BufferedImage image = new BufferedImage(width, height,
375: BufferedImage.TYPE_4BYTE_ABGR_PRE);
376: final Graphics2D g = image.createGraphics();
377: g.setPaint(paint);
378: final int lineHeight = 4;
379: g.fill3DRect(0, height / 2 - lineHeight / 2, width, lineHeight,
380: false);
381: g.dispose();
382: return new ImageIcon(image);
383: }
384:
385: /**
386: * Creates empty image.
387: *
388: * @param width
389: * @param height
390: * @return icon
391: */
392: private static ImageIcon createEmptyImageIcon(final int width,
393: final int height) {
394: final BufferedImage image = new BufferedImage(width, height,
395: BufferedImage.TYPE_4BYTE_ABGR_PRE);
396: final Graphics2D g = image.createGraphics();
397: g.dispose();
398: return new ImageIcon(image);
399: }
400:
401: private JMenuBar initMenuBar() {
402: final JMenuBar menuBar = new JMenuBar();
403:
404: fileMenu = new JMenu(localStrings
405: .getString("main_frame_menu_file"));
406: fileMenu.setMnemonic(localStrings.getString(
407: "main_frame_menu_mnemonic_file").charAt(0));
408: menuBar.add(fileMenu);
409:
410: JMenuItem menuItem = new JMenuItem(openFileAction);
411: fileMenu.add(menuItem);
412:
413: menuItem = new JMenuItem(openURLAction);
414: fileMenu.add(menuItem);
415:
416: recentURLsMenu.setIcon(createEmptyImageIcon(20, 20));
417: fileMenu.add(recentURLsMenu);
418:
419: /*
420: menuItem = new JMenuItem(addFileAction);
421: fileMenu.add(menuItem);
422: */
423:
424: exportMenuItem = new JMenuItem(exportAction);
425: fileMenu.add(exportMenuItem);
426:
427: menuItem = new JMenuItem(refreshAction);
428: fileMenu.add(menuItem);
429:
430: watchCheckBoxMenuItem = new JCheckBoxMenuItem(watchAction);
431: fileMenu.add(watchCheckBoxMenuItem);
432:
433: menuItem = new JMenuItem(exitAction);
434: fileMenu.add(menuItem);
435:
436: final JMenu viewMenu = new JMenu(localStrings
437: .getString("main_frame_menu_view"));
438:
439: viewMenu.setMnemonic(localStrings.getString(
440: "main_frame_menu_mnemonic_view").charAt(0));
441: menuBar.add(viewMenu);
442:
443: showDataPanel = new JCheckBoxMenuItem(localStrings
444: .getString("main_frame_menuitem_show_data_panel"), true);
445: showDataPanel.setMnemonic(localStrings.getString(
446: "main_frame_menuitem_mnemonic_show_data_panel").charAt(
447: 0));
448: showDataPanel.setIcon(createEmptyImageIcon(20, 20));
449: showDataPanel.setToolTipText(localStrings
450: .getString("main_frame_menuitem_hint_show_data_panel"));
451: showDataPanel.addActionListener(new ActionListener() {
452: public void actionPerformed(final ActionEvent e) {
453: final GCDocument gcDocument = getSelectedGCDocument();
454: if (gcDocument != null) {
455: gcDocument.setShowModelPanel(showDataPanel
456: .getState());
457: }
458: }
459: });
460: viewMenu.add(showDataPanel);
461: viewMenu.addSeparator();
462:
463: antiAlias = new JCheckBoxMenuItem(localStrings
464: .getString("main_frame_menuitem_antialias"), true);
465: antiAlias.setMnemonic(localStrings.getString(
466: "main_frame_menuitem_mnemonic_antialias").charAt(0));
467: antiAlias.setIcon(createEmptyImageIcon(20, 20));
468: antiAlias.setToolTipText(localStrings
469: .getString("main_frame_menuitem_hint_antialias"));
470: antiAlias.addActionListener(new ActionListener() {
471: public void actionPerformed(final ActionEvent e) {
472: final GCDocument gcDocument = getSelectedGCDocument();
473: if (gcDocument != null) {
474: gcDocument.getModelChart().setAntiAlias(
475: antiAlias.getState());
476: gcDocument.relayout();
477: }
478: }
479: });
480: antiAlias.setSelected(false);
481: viewMenu.add(antiAlias);
482: viewMenu.addSeparator();
483:
484: lines = new HashMap();
485:
486: fullGCLines = new JCheckBoxMenuItem(localStrings
487: .getString("main_frame_menuitem_full_gc_lines"), true);
488: fullGCLines
489: .setMnemonic(localStrings.getString(
490: "main_frame_menuitem_mnemonic_full_gc_lines")
491: .charAt(0));
492: fullGCLines.setToolTipText(localStrings
493: .getString("main_frame_menuitem_hint_full_gc_lines"));
494: fullGCLines.setIcon(createMonoColoredImageIcon(
495: FullGCLineRenderer.DEFAULT_LINEPAINT, 20, 20));
496: fullGCLines.setActionCommand(FULL_GC_LINES);
497: fullGCLines.addActionListener(viewActionListener);
498: viewMenu.add(fullGCLines);
499: lines.put(FULL_GC_LINES, fullGCLines);
500:
501: incGCLines = new JCheckBoxMenuItem(localStrings
502: .getString("main_frame_menuitem_inc_gc_lines"), true);
503: incGCLines.setMnemonic(localStrings.getString(
504: "main_frame_menuitem_mnemonic_inc_gc_lines").charAt(0));
505: incGCLines.setToolTipText(localStrings
506: .getString("main_frame_menuitem_hint_inc_gc_lines"));
507: incGCLines.setIcon(createMonoColoredImageIcon(
508: IncLineRenderer.DEFAULT_LINEPAINT, 20, 20));
509: incGCLines.setActionCommand(INC_GC_LINES);
510: incGCLines.addActionListener(viewActionListener);
511: viewMenu.add(incGCLines);
512: lines.put(INC_GC_LINES, incGCLines);
513:
514: gcTimesLine = new JCheckBoxMenuItem(localStrings
515: .getString("main_frame_menuitem_gc_times_line"), true);
516: gcTimesLine
517: .setMnemonic(localStrings.getString(
518: "main_frame_menuitem_mnemonic_gc_times_line")
519: .charAt(0));
520: gcTimesLine.setToolTipText(localStrings
521: .getString("main_frame_menuitem_hint_gc_times_line"));
522: gcTimesLine.setIcon(createMonoColoredImageIcon(
523: GCTimesRenderer.DEFAULT_LINEPAINT, 20, 20));
524: gcTimesLine.setActionCommand(GC_LINES_LINE);
525: gcTimesLine.addActionListener(viewActionListener);
526: viewMenu.add(gcTimesLine);
527: lines.put(GC_LINES_LINE, gcTimesLine);
528:
529: gcTimesRectangle = new JCheckBoxMenuItem(localStrings
530: .getString("main_frame_menuitem_gc_times_rectangles"),
531: true);
532: gcTimesRectangle.setMnemonic(localStrings.getString(
533: "main_frame_menuitem_mnemonic_gc_times_rectangles")
534: .charAt(0));
535: gcTimesRectangle
536: .setToolTipText(localStrings
537: .getString("main_frame_menuitem_hint_gc_times_rectangles"));
538: gcTimesRectangle.setIcon(createMonoColoredImageIcon(
539: GCRectanglesRenderer.DEFAULT_LINEPAINT, 20, 20));
540: gcTimesRectangle.setActionCommand(GC_TIMES_RECTANGLES);
541: gcTimesRectangle.addActionListener(viewActionListener);
542: viewMenu.add(gcTimesRectangle);
543: lines.put(GC_TIMES_RECTANGLES, gcTimesRectangle);
544:
545: totalMemory = new JCheckBoxMenuItem(localStrings
546: .getString("main_frame_menuitem_total_memory"), true);
547: totalMemory.setMnemonic(localStrings.getString(
548: "main_frame_menuitem_mnemonic_total_memory").charAt(0));
549: totalMemory.setToolTipText(localStrings
550: .getString("main_frame_menuitem_hint_total_memory"));
551: totalMemory.setIcon(createMonoColoredImageIcon(
552: TotalHeapRenderer.DEFAULT_LINEPAINT, 20, 20));
553: totalMemory.setActionCommand(TOTAL_MEMORY);
554: totalMemory.addActionListener(viewActionListener);
555: viewMenu.add(totalMemory);
556: lines.put(TOTAL_MEMORY, totalMemory);
557:
558: tenuredMemory = new JCheckBoxMenuItem(localStrings
559: .getString("main_frame_menuitem_tenured_memory"), true);
560: tenuredMemory.setMnemonic(localStrings.getString(
561: "main_frame_menuitem_mnemonic_tenured_memory")
562: .charAt(0));
563: tenuredMemory.setToolTipText(localStrings
564: .getString("main_frame_menuitem_hint_tenured_memory"));
565: tenuredMemory.setIcon(createMonoColoredImageIcon(
566: TotalTenuredRenderer.DEFAULT_LINEPAINT, 20, 20));
567: tenuredMemory.setActionCommand(TENURED_MEMORY);
568: tenuredMemory.addActionListener(viewActionListener);
569: viewMenu.add(tenuredMemory);
570: lines.put(TENURED_MEMORY, tenuredMemory);
571:
572: youngMemory = new JCheckBoxMenuItem(localStrings
573: .getString("main_frame_menuitem_young_memory"), true);
574: youngMemory.setMnemonic(localStrings.getString(
575: "main_frame_menuitem_mnemonic_young_memory").charAt(0));
576: youngMemory.setToolTipText(localStrings
577: .getString("main_frame_menuitem_hint_young_memory"));
578: youngMemory.setIcon(createMonoColoredImageIcon(
579: TotalYoungRenderer.DEFAULT_LINEPAINT, 20, 20));
580: youngMemory.setActionCommand(YOUNG_MEMORY);
581: youngMemory.addActionListener(viewActionListener);
582: viewMenu.add(youngMemory);
583: lines.put(YOUNG_MEMORY, youngMemory);
584:
585: usedMemory = new JCheckBoxMenuItem(localStrings
586: .getString("main_frame_menuitem_used_memory"), true);
587: usedMemory.setMnemonic(localStrings.getString(
588: "main_frame_menuitem_mnemonic_used_memory").charAt(0));
589: usedMemory.setToolTipText(localStrings
590: .getString("main_frame_menuitem_hint_used_memory"));
591: usedMemory.setIcon(createMonoColoredImageIcon(
592: UsedHeapRenderer.DEFAULT_LINEPAINT, 20, 20));
593: usedMemory.setActionCommand(USED_MEMORY);
594: usedMemory.addActionListener(viewActionListener);
595: viewMenu.add(usedMemory);
596: lines.put(USED_MEMORY, usedMemory);
597:
598: windowMenu = new JMenu(localStrings
599: .getString("main_frame_menu_window"));
600: windowMenu.setMnemonic(localStrings.getString(
601: "main_frame_menu_mnemonic_window").charAt(0));
602: menuBar.add(windowMenu);
603:
604: menuItem = new JMenuItem(arrangeAction);
605: windowMenu.add(menuItem);
606: windowMenu.addSeparator();
607:
608: final JMenu helpMenu = new JMenu(localStrings
609: .getString("main_frame_menu_help"));
610: helpMenu.setMnemonic(localStrings.getString(
611: "main_frame_menu_mnemonic_help").charAt(0));
612: menuBar.add(helpMenu);
613:
614: menuItem = new JMenuItem(aboutAction);
615: helpMenu.add(menuItem);
616:
617: return menuBar;
618: }
619:
620: private class ViewMenuActionListener implements ActionListener {
621: public void actionPerformed(final ActionEvent e) {
622: if (getSelectedGCDocument() == null)
623: return;
624: if (e.getActionCommand() == FULL_GC_LINES) {
625: getSelectedGCDocument().getModelChart()
626: .setShowFullGCLines(
627: ((JCheckBoxMenuItem) e.getSource())
628: .getState());
629: } else if (e.getActionCommand() == INC_GC_LINES) {
630: getSelectedGCDocument().getModelChart()
631: .setShowIncGCLines(
632: ((JCheckBoxMenuItem) e.getSource())
633: .getState());
634: } else if (e.getActionCommand() == GC_LINES_LINE) {
635: getSelectedGCDocument().getModelChart()
636: .setShowGCTimesLine(
637: ((JCheckBoxMenuItem) e.getSource())
638: .getState());
639: } else if (e.getActionCommand() == GC_TIMES_RECTANGLES) {
640: getSelectedGCDocument().getModelChart()
641: .setShowGCTimesRectangles(
642: ((JCheckBoxMenuItem) e.getSource())
643: .getState());
644: } else if (e.getActionCommand() == TOTAL_MEMORY) {
645: getSelectedGCDocument().getModelChart()
646: .setShowTotalMemoryLine(
647: ((JCheckBoxMenuItem) e.getSource())
648: .getState());
649: } else if (e.getActionCommand() == USED_MEMORY) {
650: getSelectedGCDocument().getModelChart()
651: .setShowUsedMemoryLine(
652: ((JCheckBoxMenuItem) e.getSource())
653: .getState());
654: } else if (e.getActionCommand() == TENURED_MEMORY) {
655: getSelectedGCDocument().getModelChart().setShowTenured(
656: ((JCheckBoxMenuItem) e.getSource()).getState());
657: } else if (e.getActionCommand() == YOUNG_MEMORY) {
658: getSelectedGCDocument().getModelChart().setShowYoung(
659: ((JCheckBoxMenuItem) e.getSource()).getState());
660: }
661: }
662: }
663:
664: public void exit() {
665: storePreferences();
666: dispose();
667: System.exit(0);
668: }
669:
670: private void loadPreferences() {
671: final File preferences = getPreferencesFile();
672: if (preferences.exists()) {
673: FileInputStream in = null;
674: try {
675: in = new FileInputStream(preferences);
676: final Properties properties = new Properties();
677: properties.load(in);
678: if (PREFERENCE_VERSION.equals(properties
679: .getProperty("preferences.version"))) {
680: for (Iterator line = lines.keySet().iterator(); line
681: .hasNext();) {
682: final String name = (String) line.next();
683: final JCheckBoxMenuItem item = (JCheckBoxMenuItem) lines
684: .get(name);
685: item.setState("true".equals(properties
686: .getProperty("view." + name, "true")));
687: viewActionListener
688: .actionPerformed(new ActionEvent(item,
689: 0, item.getActionCommand()));
690: }
691: //modelChart.setScaleFactor(getDoubleProperty(properties.getProperty("view.zoom"), 100.0d));
692: final int width = getIntegerProperty(properties
693: .getProperty("window.width"), 800);
694: final int height = getIntegerProperty(properties
695: .getProperty("window.height"), 600);
696: final int x = getIntegerProperty(properties
697: .getProperty("window.x"), 0);
698: final int y = getIntegerProperty(properties
699: .getProperty("window.y"), 0);
700: setBounds(x, y, width, height);
701: final String lastfile = properties
702: .getProperty("lastfile");
703: if (lastfile != null) {
704: openFileAction.setSelectedFile(new File(
705: lastfile));
706: }
707: // recent files
708: for (int i = 0;; i++) {
709: final String recentFiles = properties
710: .getProperty("recent." + i);
711: if (recentFiles != null) {
712: final StringTokenizer st = new StringTokenizer(
713: recentFiles, ";");
714: final URL[] urls = new URL[st.countTokens()];
715: for (int j = 0; st.hasMoreTokens(); j++) {
716: urls[j] = new URL(st.nextToken());
717: }
718: recentURLsMenu.getRecentURLsModel().add(
719: urls);
720: } else {
721: break;
722: }
723: }
724: }
725: } catch (IOException ioe) {
726: ioe.printStackTrace();
727: } finally {
728: if (in != null)
729: try {
730: in.close();
731: } catch (IOException ioe) {
732: }
733: }
734: } else {
735: setBounds(0, 0, 800, 600);
736: }
737: }
738:
739: private void storePreferences() {
740: final File preferences = getPreferencesFile();
741: if (true) {
742: FileOutputStream out = null;
743: try {
744: out = new FileOutputStream(preferences);
745: final Properties properties = new Properties();
746: for (Iterator line = lines.keySet().iterator(); line
747: .hasNext();) {
748: final String name = (String) line.next();
749: final JCheckBoxMenuItem item = (JCheckBoxMenuItem) lines
750: .get(name);
751: properties.setProperty("view."
752: + item.getActionCommand(),
753: item.getState() ? Boolean.TRUE.toString()
754: : Boolean.FALSE.toString());
755: }
756: //properties.setProperty("view.zoom", Double.toString(modelChart.getScaleFactor()));
757: properties.setProperty("window.width", Integer
758: .toString(getWidth()));
759: properties.setProperty("window.height", Integer
760: .toString(getHeight()));
761: properties.setProperty("window.x", Integer
762: .toString(getX()));
763: properties.setProperty("window.y", Integer
764: .toString(getY()));
765: properties.setProperty("preferences.version",
766: PREFERENCE_VERSION);
767: if (openFileAction.getLastSelectedFiles().length != 0) {
768: properties.setProperty("lastfile", openFileAction
769: .getLastSelectedFiles()[0]
770: .getAbsolutePath());
771: }
772: // recent files
773: final Component[] recentMenuItems = recentURLsMenu
774: .getMenuComponents();
775: for (int i = 0; i < recentMenuItems.length; i++) {
776: final OpenRecent openRecent = (OpenRecent) ((JMenuItem) recentMenuItems[i])
777: .getAction();
778: final URL[] urls = openRecent.getURLs();
779: final StringBuffer sb = new StringBuffer();
780: for (int j = 0; j < urls.length; j++) {
781: sb.append(urls[j]);
782: sb.append(';');
783: }
784: properties.setProperty("recent."
785: + (recentMenuItems.length - i - 1), sb
786: .toString());
787: }
788: properties.store(out, "GCViewer preferences "
789: + new Date());
790: } catch (IOException ioe) {
791: ioe.printStackTrace();
792: } finally {
793: if (out != null)
794: try {
795: out.close();
796: } catch (IOException ioe) {
797: }
798: }
799: }
800: }
801:
802: private int getIntegerProperty(final String stringValue,
803: final int defaultValue) {
804: int value = defaultValue;
805: try {
806: if (stringValue != null)
807: value = NumberParser.parseInt(stringValue);
808: } catch (NumberFormatException nfe) {
809: nfe.printStackTrace();
810: }
811: return value;
812: }
813:
814: // currently not used
815: /*
816: private double getDoubleProperty(String stringValue, double defaultValue) {
817: double value = defaultValue;
818: try {
819: if (stringValue != null) value = Double.parseDouble(stringValue);
820: }
821: catch (NumberFormatException nfe) {
822: nfe.printStackTrace();
823: }
824: return value;
825: }
826: */
827:
828: private File getPreferencesFile() {
829: return new File(System.getProperty("user.home")
830: + "/gcviewer.properties");
831: }
832:
833: public static void main(final String[] args) {
834: if (args.length > 1)
835: usage();
836: else {
837: SwingUtilities.invokeLater(new Runnable() {
838: public void run() {
839: final GCViewer viewer = new GCViewer();
840: if (args.length == 1) {
841: viewer.open(new File[] { new File(args[0]) });
842: }
843: }
844: });
845: }
846: }
847:
848: private static void usage() {
849: System.out.println("GCViewer");
850: System.out
851: .println("java com.tagtraum.perf.gcviewer.GCViewer [<gc-log-file>]");
852: }
853:
854: private static class WindowMenuItemAction extends AbstractAction
855: implements PropertyChangeListener {
856: private GCDocument gcDocument;
857:
858: public WindowMenuItemAction(final InternalFrameEvent e) {
859: this .gcDocument = (GCDocument) e.getInternalFrame();
860: putValue(Action.NAME, gcDocument.getTitle());
861: this .gcDocument.addPropertyChangeListener("title", this );
862: }
863:
864: public void actionPerformed(final ActionEvent ae) {
865: try {
866: gcDocument.setSelected(true);
867: } catch (PropertyVetoException e1) {
868: e1.printStackTrace();
869: }
870: }
871:
872: public GCDocument getGcDocument() {
873: return gcDocument;
874: }
875:
876: public void propertyChange(final PropertyChangeEvent evt) {
877: putValue(Action.NAME, gcDocument.getTitle());
878: }
879: }
880:
881: }
|