package org.freehep.application; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import java.awt.print.PageFormat; import java.awt.print.Pageable; import java.awt.print.Paper; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.util.Properties; import javax.print.PrintService; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.standard.JobName; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaPrintableArea; import javax.print.attribute.standard.MediaSize; import javax.print.attribute.standard.MediaSizeName; import org.freehep.application.studio.Studio; /** * * @author tonyj */ public class PrintHelper implements Printable { private static final String rootName = PrintHelper.class.getName() + "."; public final static int ORIENTATION_BEST_FIT = 0; public final static int ORIENTATION_PORTRAIT = 1; public final static int ORIENTATION_LANDSCAPE = 2; private Component target; private Font headerFooterFont = new Font("SansSerif", Font.PLAIN, 10); private PrintRequestAttributeSet atts = new HashPrintRequestAttributeSet(); private PrinterJob pj; private String footer; private String header; private Studio app; private boolean drawBorder; private boolean scaleUp; private boolean showFooter; private boolean showHeader; private int orientation; public PrintHelper(Component target, Studio app) { this.target = target; this.app = app; Properties user = app.getUserProperties(); drawBorder = PropertyUtilities.getBoolean(user, rootName + "drawBorder", false); scaleUp = PropertyUtilities.getBoolean(user, rootName + "scaleUp", false); showHeader = PropertyUtilities.getBoolean(user, rootName + "showHeader", true); showFooter = PropertyUtilities.getBoolean(user, rootName + "showFooter", false); footer = PropertyUtilities.getString(user, rootName + "footer", null); header = PropertyUtilities.getString(user, rootName + "header", "JAS3&b&d"); orientation = PropertyUtilities.getInteger(user, rootName + "orientation", ORIENTATION_BEST_FIT); pj = PrinterJob.getPrinterJob(); pj.setPrintable(this); String defaultPrinter = user.getProperty(rootName + "defaultPrinter"); PrintService ps = pj.getPrintService(); if (ps == null) throw new RuntimeException("No Print Service Found"); if ((defaultPrinter != null) && !ps.getName().equals(defaultPrinter)) { PrintService[] services = PrinterJob.lookupPrintServices(); for (int i = 0; i < services.length; i++) { if (services[i].getName().equals(defaultPrinter)) { try { pj.setPrintService(services[i]); ps = services[i]; break; } catch (PrinterException x) { x.printStackTrace(); } } } } atts.add(new JobName(user.getProperty(rootName + "printJobName", "JAS3 Plots"), null)); Media media = (Media) ps.getDefaultAttributeValue(Media.class); float x = PropertyUtilities.getFloat(user, rootName + "printArea.top", 0); float y = PropertyUtilities.getFloat(user, rootName + "printArea.left", 0); float w = PropertyUtilities.getFloat(user, rootName + "printArea.right", 0); float h = PropertyUtilities.getFloat(user, rootName + "printArea.bottom", 0); if (x > 0) atts.add(new MediaPrintableArea(x, y, w, h, MediaPrintableArea.INCH)); } public void setDrawBorder(boolean drawBorder) { this.drawBorder = drawBorder; } public boolean isDrawBorder() { return drawBorder; } public void setFooter(String footer) { this.footer = footer; } public String getFooter() { return footer; } public void setHeader(String header) { this.header = header; } public String getHeader() { return header; } public void setOrientation(int orientation) { this.orientation = orientation; } public int getOrientation() { return orientation; } public void setScaleUp(boolean scaleUp) { this.scaleUp = scaleUp; } public boolean getScaleUp() { return scaleUp; } public void setShowFooter(boolean showFooter) { this.showFooter = showFooter; } public boolean isShowFooter() { return showFooter; } public void setShowHeader(boolean showHeader) { this.showHeader = showHeader; } public boolean isShowHeader() { return showHeader; } public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { if (pi >= 1) return Printable.NO_SUCH_PAGE; Graphics2D orig = (Graphics2D) g; Graphics2D g2 = (Graphics2D) orig.create(); g2.translate(pf.getImageableX(), pf.getImageableY()); Dimension size = target.getSize(); double pageWidth = pf.getImageableWidth(); double pageHeight = pf.getImageableHeight(); double portraiteRatio = Math.min(pageWidth / size.width, pageHeight / size.height); double landscapeRatio = Math.min(pageWidth / size.height, pageHeight / size.width); if (!scaleUp) { portraiteRatio = Math.min(portraiteRatio, 1); landscapeRatio = Math.min(landscapeRatio, 1); } boolean useLandscape = (orientation == ORIENTATION_BEST_FIT) ? (landscapeRatio > portraiteRatio) : (orientation == ORIENTATION_LANDSCAPE); if (useLandscape) { g2.rotate(Math.PI / 2); g2.translate(0, -pageWidth); g2.scale(landscapeRatio, landscapeRatio); } else { g2.scale(portraiteRatio, portraiteRatio); } target.print(g2); g2.dispose(); if (drawBorder) { orig.setColor(Color.BLACK); orig.draw(new Rectangle2D.Double(pf.getImageableX(), pf.getImageableY(), pageWidth, pageHeight)); } return Printable.PAGE_EXISTS; } void pageDialog(Component parent) { pj.pageDialog(atts); } public void print() throws PrinterException { pj.print(atts); commitChanges(); } void printDialog(Component parent) { pj.printDialog(atts); } public void printPreview(Component parent) throws PrinterException { PrintPreview pp = new PrintPreview() { protected boolean onPrint(Pageable document) throws PrinterException { PrintHelper.this.print(); return true; } protected void onError(PrinterException x) { app.error(this, "Print Error", x); } }; // We need to get a PageFormat object corresponding to the current attributes PageFormat pf = pj.defaultPage(); Media media = (Media) atts.get(Media.class); if (media instanceof MediaSizeName) { MediaSize ms = MediaSize.getMediaSizeForName((MediaSizeName) media); MediaPrintableArea ma = (MediaPrintableArea) atts.get(MediaPrintableArea.class); //Orientation Paper paper = pf.getPaper(); paper.setSize(72 * ms.getX(ms.INCH), 72 * ms.getY(ms.INCH)); paper.setImageableArea(72 * ma.getX(ma.INCH), 72 * ma.getY(ma.INCH), 72 * ma.getWidth(ma.INCH), 72 * ma.getHeight(ma.INCH)); pf.setPaper(paper); } pp.setPrintable(this, pf); app.showDialog(pp.createDialog(parent), "printPreview"); } public void showOptionsDialog(Component parent) { PrintDialog pd = new PrintDialog(app, this); int rc = pd.showDialog(parent); if (rc == pd.OK_OPTION) { commitChanges(); } } private void commitChanges() { Properties user = app.getUserProperties(); PropertyUtilities.setBoolean(user, rootName + "drawBorder", drawBorder); PropertyUtilities.setBoolean(user, rootName + "scaleUp", scaleUp); PropertyUtilities.setBoolean(user, rootName + "showHeader", showHeader); PropertyUtilities.setBoolean(user, rootName + "showFooter", showFooter); PropertyUtilities.setString(user, rootName + "footer", footer); PropertyUtilities.setString(user, rootName + "header", header); PropertyUtilities.setInteger(user, rootName + "orientation", orientation); PropertyUtilities.setString(user, rootName + "defaultPrinter", pj.getPrintService().getName()); JobName jobName = (JobName) atts.get(JobName.class); if (jobName != null) PropertyUtilities.setString(user, rootName + "printJobName", jobName.getName()); MediaPrintableArea mp = (MediaPrintableArea) atts.get(MediaPrintableArea.class); if (mp != null) { PropertyUtilities.setFloat(user, rootName + "printArea.x", mp.getX(mp.INCH)); PropertyUtilities.setFloat(user, rootName + "printArea.y", mp.getY(mp.INCH)); PropertyUtilities.setFloat(user, rootName + "printArea.w", mp.getWidth(mp.INCH)); PropertyUtilities.setFloat(user, rootName + "printArea.h", mp.getHeight(mp.INCH)); } Media media = (Media) atts.get(Media.class); if (media instanceof MediaSizeName) { MediaSize ms = MediaSize.getMediaSizeForName((MediaSizeName) media); PropertyUtilities.setString(user, rootName + "mediaSize", media.getName()); } } }