Java 根据打印页面调整/缩放JC组件

Java 根据打印页面调整/缩放JC组件,java,swing,printing,graphics2d,Java,Swing,Printing,Graphics2d,我正在尝试缩放我的组件,以便它可以适合单个打印页面(纵向或横向) 是我试图打印的组件(JPanel) 这是我到目前为止得到的依据 我对图形不太熟悉,因此如果有任何帮助,我将不胜感激。基本概念是使用仿射变换对结果输出进行缩放 在我的测试中,我能够拍摄7680x4800的图像并打印在595x842的页面上(按93%的比例缩小) 这使用了AffineTransformOp。使用begin缩放的组件是否适合页面?@MadProgrammer Hi-对不起,我不理解你的问题,这应该是“未缩放”的。也就是说

我正在尝试缩放我的组件,以便它可以适合单个打印页面(纵向或横向)

是我试图打印的组件(JPanel)

这是我到目前为止得到的依据


我对图形不太熟悉,因此如果有任何帮助,我将不胜感激。基本概念是使用
仿射变换
对结果输出进行缩放

在我的测试中,我能够拍摄7680x4800的图像并打印在595x842的页面上(按93%的比例缩小)


这使用了
AffineTransformOp
。使用begin缩放的组件是否适合页面?@MadProgrammer Hi-对不起,我不理解你的问题,这应该是“未缩放”的。也就是说,如果你什么都不做,它会出现在页面上吗?将组件的大小更改为与页面大小匹配,将所有内容都放在上面…@MadProgrammer有时它会放在A4纸上。但是,通常情况下,否-需要缩小。应//打印组件comp.printAll(g2);是comp.paintAll(g2)?如果没有,有什么区别有许多不同之处。首先,Swing组件是双缓冲的,这使得更新更加无缝,打印时不需要这种开销。此外,您还可以自定义打印输出(这一点您并不在意)。此外,如果未连接到本机对等机(即未显示在屏幕上),我看到组件抛出异常。它是
printAll
,没有
paintAll
方法;)酷。您的意思是两者都有compSize.width吗?/计算缩放的大小。。。双刻度宽度=compSize.WITH*刻度因子;双刻度高度=compSize.width*刻度因子;此外,我们是否需要考虑论文的方向?这会影响你的居中吗?我不这么认为,在风景中,宽度和高度已经(从内存中)交换了-试试看;)
 gDiagram.getComponent()
/**
 * 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);
    }
}
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;

    }
}