package net.sourceforge.fidocadj.dialogs.print; import javax.swing.*; import javax.swing.border.EtchedBorder; import javax.print.attribute.*; import javax.print.attribute.standard.*; import java.awt.print.*; import java.awt.event.*; import java.awt.image.*; import java.awt.geom.AffineTransform; import java.awt.*; import net.sourceforge.fidocadj.circuit.*; import net.sourceforge.fidocadj.circuit.controllers.ParserActions; import net.sourceforge.fidocadj.globals.*; import net.sourceforge.fidocadj.geom.*; import net.sourceforge.fidocadj.*; /** Shows a print preview. <pre> This file is part of FidoCadJ. FidoCadJ 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 3 of the License, or (at your option) any later version. FidoCadJ 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 FidoCadJ. If not, @see <a href=http://www.gnu.org/licenses/>http://www.gnu.org/licenses/</a>. Copyright 2015 by Davide Bucci </pre> @author Davide Bucci */ public class PrintPreview extends CircuitPanel implements ComponentListener { private final PageFormat pageDescription; private double topMargin; private double bottomMargin; private double leftMargin; private double rightMargin; private BufferedImage pageImage; private final PrintTools printObject; private final DialogPrint dialog; private int currentPage; private double oldBaseline; /** Constructor. @param isEditable true if the panel should be editable. @param p the PageFormat description. @param ddp the DialogPrint object to communicate with. */ public PrintPreview(boolean isEditable, PageFormat p, DialogPrint ddp) { super(isEditable); pageDescription=p; currentPage=0; dialog=ddp; setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); setGridVisibility(false); addComponentListener(this); int width=200; int height=320; pageImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); printObject=new PrintTools(); printObject.associateToCircuitPanel(this); printObject.setShowMargins(true); Graphics2D g2=(Graphics2D)pageImage.createGraphics(); g2.setColor(Color.white); g2.fillRect(0,0,width,height); g2.scale(1.0/160,1.0/160); try { printObject.print(g2, pageDescription, 0); } catch (PrinterException pe) { System.err.println("Some problem here!"); } } /** Set the size of the margins, in centimeters. The orientation of those margins should correspond to the page in the portrait orientation. @param tm top margin. @param bm bottom margin. @param lm left margin. @param rm right margin. */ public void setMargins(double tm, double bm, double lm, double rm) { topMargin=tm; bottomMargin=bm; leftMargin=lm; rightMargin=rm; } /** Set the current page to be printed. @param p the page to be printed. @return the number of the selected page (it may differ from the one which is passed as an argument, since a sanity check is done). */ public int setCurrentPage(int p) { pageImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); Graphics2D g2=(Graphics2D)pageImage.createGraphics(); try { if (printObject.print(g2, pageDescription, p) ==Printable.PAGE_EXISTS) { currentPage=p; } else { currentPage=0; } } catch (PrinterException pe) { currentPage=0; } return currentPage; } /** Show the margins. @param g the graphic context where to draw. */ @Override public void paintComponent(Graphics g) { getDrawingModel().setChanged(true); // Needed? Color c = g.getColor(); Graphics2D g2d = (Graphics2D) g; int shadowShiftX=4; int shadowShiftY=4; double baseline=getWidth()*0.6; if(Math.abs(oldBaseline-baseline)>1e5) /// ??? 1e-5 I would say!!! updatePreview(); double ratio=pageDescription.getHeight()/pageDescription.getWidth(); if(dialog.getLandscape()) { baseline=getWidth()*0.8; pageDescription.setOrientation(pageDescription.LANDSCAPE); } else { pageDescription.setOrientation(pageDescription.PORTRAIT); } // Draw the background. g2d.setColor(getBackground()); g2d.fillRect(0,0,getWidth(), getHeight()); // Draw the shadow of the page. g2d.setColor(Color.gray.darker()); g2d.fillRect((int)Math.round(getWidth()/2.0-baseline/2.0)+shadowShiftX, (int)Math.round(getHeight()/2.0-baseline*ratio/2.0)+shadowShiftY, (int)Math.round(baseline), (int)Math.round(baseline*ratio)); // Draw the image containing the preview. g2d.drawImage(pageImage, (int)Math.round(getWidth()/2.0-baseline/2.0), (int)Math.round(getHeight()/2.0-baseline*ratio/2.0), null); // Draw the contour of the page. g2d.setColor(Color.black); g2d.drawRect((int)Math.round(getWidth()/2.0-baseline/2.0), (int)Math.round(getHeight()/2.0-baseline*ratio/2.0), (int)Math.round(baseline)-1, (int)Math.round(baseline*ratio)); g2d.setColor(c); } /** Called when the panel is resized. TODO: this is not very memory efficient, since an image is created each time the panel is resized. @param e the event descriptor. */ public void componentResized(ComponentEvent e) { updatePreview(); } /** Update the printing preview by calculating again the image containing it. It will be shown at the following repaint operation. */ public void updatePreview() { printObject.configurePrinting(dialog, pageDescription, false); double baseline=getWidth()*0.6; double pageWidth=pageDescription.getWidth(); double pageHeight=pageDescription.getHeight(); double ratio=pageHeight/pageWidth; if(dialog.getLandscape()) { baseline=getWidth()*0.8; pageDescription.setOrientation(pageDescription.LANDSCAPE); } else { pageDescription.setOrientation(pageDescription.PORTRAIT); } int width=(int)baseline; int height=(int)Math.round(baseline*ratio); if(width<1) width=1; if(height<1) height=1; pageImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d=(Graphics2D)pageImage.createGraphics(); AffineTransform oldTransform = g2d.getTransform(); // Activate anti-aliasing g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(Color.white); g2d.fillRect(0,0,width,height); g2d.scale(width/pageWidth, height/pageHeight); try { printObject.setMargins(topMargin, bottomMargin, leftMargin, rightMargin); printObject.print(g2d, pageDescription, currentPage); } catch (PrinterException pe) { System.err.println("Some problem here!"); } g2d.setTransform(oldTransform); oldBaseline=baseline; } /** Get the total number of pages in the preview. @return the number of pages. */ public int getTotalNumberOfPages() { int numpages=0; pageImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); Graphics2D g2=(Graphics2D)pageImage.createGraphics(); try { while(printObject.print(g2, pageDescription, numpages) ==Printable.PAGE_EXISTS) { ++numpages; } } catch (PrinterException pe) { System.err.println("Some problems when trying to print."); } return numpages; } /** Called when the panel is hidden. @param e the event descriptor. */ public void componentHidden(ComponentEvent e) { // Nothing to do here } /** Called when the panel is moved. @param e the event descriptor. */ public void componentMoved(ComponentEvent e) { // Nothing to do here } /** Called when the panel is shown. @param e the event descriptor. */ public void componentShown(ComponentEvent e) { // Nothing to do here } }