/* * Copyright 2006-2016 The MZmine 3 Development Team * * This file is part of MZmine 3. * * MZmine 3 is free software; you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * MZmine 3 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 for more details. * * You should have received a copy of the GNU General Public License along with MZmine 3; if not, * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ package io.github.mzmine.util.jfreechart; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.print.PageFormat; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.swing.SwingUtilities; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D; import org.freehep.graphicsio.emf.EMFGraphics2D; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.fx.ChartViewer; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.util.ExportUtils; import io.github.mzmine.gui.MZmineGUI; import javafx.scene.SnapshotParameters; import javafx.scene.image.WritableImage; import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; public class JFreeChartUtils { private static File lastSaveDirectory; public enum ImgFileType { JPG, PNG, SVG, PDF, EMF, EPS }; public static void printChart(ChartViewer chartNode) { // As of java 1.8.0_74, the JavaFX printing support seems to do poor // job. It creates pixelated, low-resolution print outs. For that // reason, we use the AWT PrinterJob class, until the JavaFX printing // support is improved. SwingUtilities.invokeLater(() -> { PrinterJob job = PrinterJob.getPrinterJob(); PageFormat pf = job.defaultPage(); PageFormat pf2 = job.pageDialog(pf); if (pf2 == pf) return; ChartPanel p = new ChartPanel(chartNode.getChart()); job.setPrintable(p, pf2); if (!job.printDialog()) return; try { job.print(); } catch (PrinterException e) { e.printStackTrace(); MZmineGUI.displayMessage("Error printing: " + e.getMessage()); } }); } public static void showSaveDialog(ChartViewer chartNode, ImgFileType fileType) { FileChooser fileChooser = new FileChooser(); switch (fileType) { case JPG: fileChooser.setTitle("Export to JPG"); fileChooser.getExtensionFilters().add(new ExtensionFilter("JPEG", "*.jpg")); break; case PNG: fileChooser.setTitle("Export to PNG"); fileChooser.getExtensionFilters() .add(new ExtensionFilter("Portable Network Graphics (PNG)", "*.png")); break; case SVG: fileChooser.setTitle("Export to SVG"); fileChooser.getExtensionFilters() .add(new ExtensionFilter("Scalable Vector Graphics (SVG)", "*.svg")); break; case PDF: fileChooser.setTitle("Export to PDF"); fileChooser.getExtensionFilters() .add(new ExtensionFilter("Portable Document Format (PDF)", "*.pdf")); break; case EMF: fileChooser.setTitle("Export to EMF"); fileChooser.getExtensionFilters().add(new ExtensionFilter("EMF image", "*.emf")); break; case EPS: fileChooser.setTitle("Export to EPS"); fileChooser.getExtensionFilters().add(new ExtensionFilter("EPS Image", "*.eps")); break; } // Remember last directory if (lastSaveDirectory != null && lastSaveDirectory.isDirectory()) fileChooser.setInitialDirectory(lastSaveDirectory); // Show the file chooser File file = fileChooser.showSaveDialog(chartNode.getScene().getWindow()); // If nothing was chosen, quit if (file == null) return; // Save the last open directory lastSaveDirectory = file.getParentFile(); // Do the export in a new thread final File finalFile = file; new Thread(() -> { exportToImageFile(chartNode, finalFile, fileType); }).start(); } public static void exportToClipboard(ChartViewer chartNode) { final Clipboard clipboard = Clipboard.getSystemClipboard(); final ClipboardContent content = new ClipboardContent(); final int width = (int) chartNode.getWidth(); final int height = (int) chartNode.getHeight(); WritableImage img = new WritableImage(width, height); SnapshotParameters params = new SnapshotParameters(); chartNode.snapshot(params, img); content.putImage(img); clipboard.setContent(content); } public static void exportToImageFile(ChartViewer chartNode, File file, ImgFileType fileType) { final JFreeChart chart = chartNode.getChart(); final int width = (int) chartNode.getWidth(); final int height = (int) chartNode.getHeight(); try { switch (fileType) { case JPG: ExportUtils.writeAsJPEG(chart, width, height, file); break; case PNG: ExportUtils.writeAsPNG(chart, width, height, file); break; case SVG: setDrawSeriesLineAsPath(chart, true); ExportUtils.writeAsSVG(chart, width, height, file); setDrawSeriesLineAsPath(chart, false); break; case PDF: setDrawSeriesLineAsPath(chart, true); ExportUtils.writeAsPDF(chart, width, height, file); setDrawSeriesLineAsPath(chart, false); break; case EMF: FileOutputStream out2 = new FileOutputStream(file); setDrawSeriesLineAsPath(chart, true); EMFGraphics2D g2d2 = new EMFGraphics2D(out2, new Dimension(width, height)); g2d2.startExport(); chart.draw(g2d2, new Rectangle(width, height)); g2d2.endExport(); setDrawSeriesLineAsPath(chart, false); break; case EPS: FileOutputStream out = new FileOutputStream(file); setDrawSeriesLineAsPath(chart, true); EPSDocumentGraphics2D g2d = new EPSDocumentGraphics2D(false); g2d.setGraphicContext(new GraphicContext()); g2d.setupDocument(out, width, height); chart.draw(g2d, new Rectangle(width, height)); g2d.finish(); setDrawSeriesLineAsPath(chart, false); out.close(); break; } } catch (IOException e) { MZmineGUI.displayMessage("Unable to save image: " + e.getMessage()); e.printStackTrace(); } } private static void setDrawSeriesLineAsPath(JFreeChart chart, boolean usePath) { final XYPlot plot = chart.getXYPlot(); for (int i = 0; i < plot.getRendererCount(); i++) { XYItemRenderer renderer = plot.getRenderer(i); if (renderer instanceof XYLineAndShapeRenderer) { XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) renderer; r.setDrawSeriesLineAsPath(usePath); } } } }