printrequestattributeset print example java swing printing graphics2d

printrequestattributeset - java print example



Ajustar/Escalar JComponent a la página que se está imprimiendo (1)

Estoy intentando escalar mi componente para que pueda caber en una sola página impresa (retrato o paisaje)

gDiagram.getComponent()

es el componente (JPanel) que intento imprimir.

Esto es lo que he basado hasta ahora en ¿Cómo puedo imprimir el contenido de un solo JPanel?

/** * Prints the diagram. */ public void printDiagram() { PrinterJob pj = PrinterJob.getPrinterJob(); pj.setJobName(" Print Component "); pj.setPrintable(new Printable() { @Override public int print(Graphics g, PageFormat pf, int pageNumber) throws PrinterException { // TODO Auto-generated method stub if (pageNumber > 0) { return Printable.NO_SUCH_PAGE; } Graphics2D g2 = (Graphics2D) g; g2.translate(pf.getImageableX(), pf.getImageableY()); double sx = pf.getImageableWidth() / gDiagram.getComponent().getWidth(); double sy = pf.getImageableHeight() / gDiagram.getComponent().getHeight(); gDiagram.getComponent().paint(g2); g2.scale(sx, sy); return Printable.PAGE_EXISTS; } }); if (!pj.printDialog()) { return; } try { pj.print(); } catch (PrinterException ex) { System.out.println(ex); } }

No estoy muy familiarizado con los gráficos, por lo que cualquier ayuda sería apreciada


El concepto básico es usar una AffineTransformation para proporcionar escalado al resultado resultante.

En mis pruebas, pude tomar una imagen de 7680x4800 y obtener una impresión en una página de 595x842 (reducida en un 93%)

import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.AffineTransform; import java.awt.geom.Dimension2D; import java.awt.image.BufferedImage; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class PrintTest { public static void main(String[] args) { new PrintTest(); } public PrintTest() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } final TestPane imagePane = new TestPane(); JButton print = new JButton("Print"); print.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { printComponent(imagePane); } }); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(imagePane); frame.add(print, BorderLayout.SOUTH); frame.setSize(200, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage bg; public TestPane() { try { bg = ImageIO.read(new File("path/to/a/image")); } catch (IOException ex) { Logger.getLogger(PrintTest.class.getName()).log(Level.SEVERE, null, ex); } } @Override public Dimension getPreferredSize() { return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (bg != null) { int x = (getWidth() - bg.getWidth()) / 2; int y = (getHeight() - bg.getHeight()) / 2; g2d.drawImage(bg, x, y, this); } g2d.dispose(); } } public void printComponent(Component comp) { PrinterJob pj = PrinterJob.getPrinterJob(); pj.setJobName(" Print Component "); pj.setPrintable(new ComponentPrintable(comp)); if (!pj.printDialog()) { return; } try { pj.print(); } catch (PrinterException ex) { System.out.println(ex); } } public class ComponentPrintable implements Printable { private Component comp; private ComponentPrintable(Component comp) { this.comp = comp; } @Override public int print(Graphics g, PageFormat pf, int pageNumber) throws PrinterException { // TODO Auto-generated method stub if (pageNumber > 0) { return Printable.NO_SUCH_PAGE; } // Get the preferred size ofthe component... Dimension compSize = comp.getPreferredSize(); // Make sure we size to the preferred size comp.setSize(compSize); // Get the the print size Dimension printSize = new Dimension(); printSize.setSize(pf.getImageableWidth(), pf.getImageableHeight()); // Calculate the scale factor double scaleFactor = getScaleFactorToFit(compSize, printSize); // Don''t want to scale up, only want to scale down if (scaleFactor > 1d) { scaleFactor = 1d; } // Calcaulte the scaled size... double scaleWidth = compSize.width * scaleFactor; double scaleHeight = compSize.height * scaleFactor; // Create a clone of the graphics context. This allows us to manipulate // the graphics context without begin worried about what effects // it might have once we''re finished Graphics2D g2 = (Graphics2D) g.create(); // Calculate the x/y position of the component, this will center // the result on the page if it can double x = ((pf.getImageableWidth() - scaleWidth) / 2d) + pf.getImageableX(); double y = ((pf.getImageableHeight() - scaleHeight) / 2d) + pf.getImageableY(); // Create a new AffineTransformation AffineTransform at = new AffineTransform(); // Translate the offset to out "center" of page at.translate(x, y); // Set the scaling at.scale(scaleFactor, scaleFactor); // Apply the transformation g2.transform(at); // Print the component comp.printAll(g2); // Dispose of the graphics context, freeing up memory and discarding // our changes g2.dispose(); comp.revalidate(); return Printable.PAGE_EXISTS; } } public static double getScaleFactorToFit(Dimension original, Dimension toFit) { double dScale = 1d; if (original != null && toFit != null) { double dScaleWidth = getScaleFactor(original.width, toFit.width); double dScaleHeight = getScaleFactor(original.height, toFit.height); dScale = Math.min(dScaleHeight, dScaleWidth); } return dScale; } public static double getScaleFactor(int iMasterSize, int iTargetSize) { double dScale = 1; if (iMasterSize > iTargetSize) { dScale = (double) iTargetSize / (double) iMasterSize; } else { dScale = (double) iTargetSize / (double) iMasterSize; } return dScale; } }