public void render(GCModel model, String chartFilePath) throws IOException { GCPreferences gcPreferences = new GCPreferences(); gcPreferences.load(); final ModelChartImpl pane = new ModelChartImpl(); pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); pane.setModel(model, gcPreferences); pane.setFootprint(model.getFootprint()); pane.setMaxPause(model.getPause().getMax()); pane.setRunningTime(model.getRunningTime()); Dimension d = new Dimension(gcPreferences.getWindowWidth(), gcPreferences.getWindowHeight()); pane.setSize(d); pane.addNotify(); pane.validate(); pane.autoSetScaleFactor(); final BufferedImage image = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB); final Graphics2D graphics = image.createGraphics(); graphics.setBackground(Color.WHITE); graphics.clearRect(0, 0, image.getWidth(), image.getHeight()); pane.paint(graphics); ImageIO.write(image, "png", new File(chartFilePath)); }
public ModelChartImpl() { super(); this.model = new GCModel(true); this.chart = new Chart(); this.chart.setPreferredSize(new Dimension(0, 0)); setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); // set scrolling speed horizontalScrollBar = getHorizontalScrollBar(); horizontalScrollBar.setUnitIncrement(50); horizontalScrollBar.setBlockIncrement(500); // order of the renderers determines what is painted first and last // we start with what's painted last GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 2; gridBagConstraints.weighty = 2; gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; initialMarkLevelRenderer = new InitialMarkLevelRenderer(this); chart.add(initialMarkLevelRenderer, gridBagConstraints); usedHeapRenderer = new UsedHeapRenderer(this); chart.add(usedHeapRenderer, gridBagConstraints); gcTimesRenderer = new GCTimesRenderer(this); chart.add(gcTimesRenderer, gridBagConstraints); fullGCLineRenderer = new FullGCLineRenderer(this); chart.add(fullGCLineRenderer, gridBagConstraints); gcRectanglesRenderer = new GCRectanglesRenderer(this); chart.add(gcRectanglesRenderer, gridBagConstraints); incLineRenderer = new IncLineRenderer(this); chart.add(incLineRenderer, gridBagConstraints); concurrentGcLineRenderer = new ConcurrentGcBegionEndRenderer(this); chart.add(concurrentGcLineRenderer, gridBagConstraints); totalTenuredRenderer = new TotalTenuredRenderer(this); chart.add(totalTenuredRenderer, gridBagConstraints); totalYoungRenderer = new TotalYoungRenderer(this); chart.add(totalYoungRenderer, gridBagConstraints); totalHeapRenderer = new TotalHeapRenderer(this); chart.add(totalHeapRenderer, gridBagConstraints); setViewportView(chart); // This would make scrolling slower, but eliminates flickering... // getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE); JPanel rowHeaderPanel = new JPanel(); GridBagLayout layout = new GridBagLayout(); rowHeaderPanel.setLayout(layout); GridBagConstraints constraints = new GridBagConstraints(); constraints.fill = GridBagConstraints.VERTICAL; constraints.weightx = 2; constraints.weighty = 1; constraints.gridheight = 2; constraints.gridx = 0; constraints.gridy = 1; this.memoryRuler = new Ruler(true, 0, model.getFootprint(), "K"); this.pauseRuler = new Ruler(true, 0, model.getPause().getMax(), "s"); layout.setConstraints(memoryRuler, constraints); rowHeaderPanel.add(memoryRuler); constraints.gridx = 1; layout.setConstraints(pauseRuler, constraints); rowHeaderPanel.add(pauseRuler); setRowHeaderView(rowHeaderPanel); setCorner(JScrollPane.UPPER_LEFT_CORNER, new JPanel()); setCorner(JScrollPane.LOWER_LEFT_CORNER, new JPanel()); DateFormat dateFormatter = new TimeFormat(); this.timestampRuler = new Ruler(false, 0, model.getRunningTime(), "", dateFormatter); setColumnHeaderView(timestampRuler); getViewport() .addComponentListener( new ComponentListener() { public void componentResized(ComponentEvent e) { chart.setSize(chart.getPreferredSize()); memoryRuler.setSize( (int) memoryRuler.getPreferredSize().getWidth(), e.getComponent().getHeight()); pauseRuler.setSize( (int) pauseRuler.getPreferredSize().getWidth(), e.getComponent().getHeight()); timestampRuler.setSize( (int) chart.getPreferredSize().getWidth(), (int) timestampRuler.getPreferredSize().getHeight()); } public void componentMoved(ComponentEvent e) {} public void componentShown(ComponentEvent e) {} public void componentHidden(ComponentEvent e) {} }); // timestamp menu final JPopupMenu popupMenu = new JPopupMenu(); timeOffsetPanel = new TimeOffsetPanel(popupMenu); popupMenu.add(timeOffsetPanel); final JPopupMenu timestampRulerPopup = popupMenu; Action setOffsetAction = new AbstractAction() { public void actionPerformed(ActionEvent e) { if (timeOffsetPanel.isOffsetSet()) timestampRuler.setOffset(timeOffsetPanel.getDate().getTime() / 1000); else timestampRuler.setOffset(0); timestampRuler.revalidate(); timestampRuler.repaint(); } }; timeOffsetPanel.setOkAction(setOffsetAction); this.timestampRuler.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) { maybePopup(e); } public void mouseReleased(MouseEvent e) { maybePopup(e); } public void maybePopup(MouseEvent e) { if (e.isPopupTrigger()) { if (timestampRuler.getOffset() != 0) { timeOffsetPanel.setDate(new Date((long) timestampRuler.getOffset() * 1000)); timeOffsetPanel.setOffsetSet(true); } else { long suggestedStartDate = model.getLastModified(); if (model.hasDateStamp()) { suggestedStartDate = (long) (model.getFirstDateStamp().getTime()); } else if (model.hasCorrectTimestamp()) { suggestedStartDate -= (long) (model.getRunningTime() * 1000.0d); } timeOffsetPanel.setDate(new Date(suggestedStartDate)); timeOffsetPanel.setOffsetSet(false); } timestampRulerPopup.show(e.getComponent(), e.getX(), e.getY()); timeOffsetPanel.requestFocus(); } } }); }