一尘不染

设置jLabel的打印尺寸并将jRadiobutton放在打印上

java

我有一个带图标的jLabel,应该打印。但是,我无法将jLabel的图标放大。

这是一些我认为会影响打印尺寸的代码。

 public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
    Paper paper = new Paper();
    paper.setSize(8.3 * 72, 11.7 * 72); //here
    paper.setImageableArea(18, 18, 100, 300); //and here

    PageFormat pf = new PageFormat();
    pf.setPaper(paper);
    pf.setOrientation(PageFormat.LANDSCAPE);

    BufferedImage img = new BufferedImage(
            (int) Math.round(pf.getWidth()),
            (int) Math.round(pf.getHeight()),
            BufferedImage.TYPE_INT_RGB);

    Graphics2D g2d = img.createGraphics();
    g2d.setColor(Color.WHITE);
    g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
    ComponentPrinter cp = new ComponentPrinter(comp, fill);
    try {
        cp.print(g2d, pf, 0);
    } finally {
        g2d.dispose();
    }

    try {
        ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

public static class ComponentPrinter implements Printable {

    private Component comp;
    private boolean fill;

    public ComponentPrinter(Component comp, boolean fill) {
        this.comp = comp;
        this.fill = fill;
    }

    @Override
    public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {

        if (page_index > 0) {
            return Printable.NO_SUCH_PAGE;
        }

        Graphics2D g2 = (Graphics2D) g;
        g2.translate(format.getImageableX(), format.getImageableY());

        double width = (int) Math.floor(format.getImageableWidth()); // here too
        double height = (int) Math.floor(format.getImageableHeight()); // and here

        if (!fill) {

            width = Math.min(width, comp.getPreferredSize().width); // here
            height = Math.min(height, comp.getPreferredSize().height); // here

        }

        comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
        if (comp.getParent() == null) {
            comp.addNotify();
        }
        comp.validate();
        comp.doLayout();
        comp.printAll(g2);
        if (comp.getParent() != null) {
            comp.removeNotify();
        }

        return Printable.PAGE_EXISTS;
    }

}

那我该如何改变呢?另外,如何在打印过程中放置单选按钮?这是因为我想一起打印带有标签的单选按钮。

这是我使用按钮打印标签的方式:

  private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    try {       
        printComponent(jLabel2, false);
    } catch (PrinterException ex) {
        Logger.getLogger(MappingScreen.class.getName()).log(Level.SEVERE, null, ex);
    }

}

我可以这样吗?:

  private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    try {       
        printComponent(jLabel2, false);
        printComponent(jRadioBtn1, false); //change
    } catch (PrinterException ex) {
        Logger.getLogger(M.class.getName()).log(Level.SEVERE, null, ex);
    }

}

更新:

我想我必须在这里添加一些内容以打印另一个组件:

 public static void main(String args[]) {
    try {
        JLabel label = new JLabel(
                "This is a test",
                new ImageIcon("/adv/mapp.jpg"),
                JLabel.CENTER);
        printComponentToFile(label, true);
        printComponentToFile(label, false);
    } catch (PrinterException exp) {
        exp.printStackTrace();
    }

Please help. Thanks


阅读 197

收藏
2020-09-08

共1个答案

一尘不染

因此,基于“ 打印JFrame及其组件”中介绍的概念,我已经能够生成这两个示例……

正常填充

使用以下内容JPanel作为基本组成部分…

public static class PrintForm extends JPanel {

    public PrintForm() {
        setLayout(new GridBagLayout());
        JLabel label = new JLabel("This is a label");
        label.setVerticalTextPosition(JLabel.BOTTOM);
        label.setHorizontalTextPosition(JLabel.CENTER);
        try {
            label.setIcon(new ImageIcon(ImageIO.read(new File("C:\\hold\\thumbnails\\_cg_1009___Afraid___by_Serena_Clearwater.png"))));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.weighty = 1;
        add(label, gbc);

        JRadioButton rb = new JRadioButton("Open to suggestions");
        rb.setSelected(true);
        gbc.gridy++;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.NONE;
        add(rb, gbc);
    }

}

基于“ 适合/缩放JComponent”中提出的要打印页面的概念,我能够拍摄7680x4800的图像并将其缩小以在842x598的区域内进行打印。

现在注意。JLabel不支持缩放。如果您的图片无法容纳到可用空间中,则您将需要自己进行一些缩放。在下面的解决方案扩展了整个组件,话说回来,用巧妙的重新排列的点点,这将有可能使TestPane缩放的图像,而不是和使用上面的例子,而不是…

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
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.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 ScalablePrintingTest {

    public static void main(String[] args) {
        new ScalablePrintingTest();
    }

    public ScalablePrintingTest() {
        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) {
                        try {
                            //printComponent(imagePane);
                            printComponentToFile(imagePane);
                        } catch (PrinterException ex) {
                            ex.printStackTrace();
                        }
                    }
                });

                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) {
                ex.printStackTrace();
            }
        }

        @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 static void printComponentToFile(Component comp) throws PrinterException {
        Paper paper = new Paper();
        paper.setSize(8.3 * 72, 11.7 * 72);
        paper.setImageableArea(18, 18, 559, 783);

        PageFormat pf = new PageFormat();
        pf.setPaper(paper);
        pf.setOrientation(PageFormat.LANDSCAPE);

        BufferedImage img = new BufferedImage(
                (int) Math.round(pf.getWidth()),
                (int) Math.round(pf.getHeight()),
                BufferedImage.TYPE_INT_RGB);

        Graphics2D g2d = img.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
        ComponentPrintable cp = new ComponentPrintable(comp);
        try {
            cp.print(g2d, pf, 0);
        } finally {
            g2d.dispose();
        }

        try {
            ImageIO.write(img, "png", new File("Page-Scaled.png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static 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;
    }
}
2020-09-08