如何在Java中打印JPanel?

4
我正在尝试制作一个Swing应用程序。现在我的目标是打印收据。我已经在JPanel上设置了所有细节。我正在尝试在Java中打印JPanel,但它会打印一个空白文档。
在JPanel中,我想要打印这个: 我只想打印白色面板 代码:
1.ActionListener

btnPrint.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            PrinterJob pjob = PrinterJob.getPrinterJob();
            PageFormat preformat = pjob.defaultPage();
            preformat.setOrientation(PageFormat.LANDSCAPE);
            PageFormat postformat = pjob.pageDialog(preformat);
            //If user does not hit cancel then print.
            if (preformat != postformat) {
                //Set print component
                pjob.setPrintable(new Printer(printPanel), postformat);
                if (pjob.printDialog()) {
                    try {
                        pjob.print();
                    } catch (PrinterException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    });

2.打印机类:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

public class Printer implements Printable { 
   final Component comp;

public Printer(Component comp){
    this.comp = comp;
}

@Override
public int print(Graphics g, PageFormat format, int page_index) 
        throws PrinterException {
    if (page_index > 0) {
        return Printable.NO_SUCH_PAGE;
    }

    // get the bounds of the component
    Dimension dim = comp.getSize();
    double cHeight = dim.getHeight();
    double cWidth = dim.getWidth();

    // get the bounds of the printable area
    double pHeight = format.getImageableHeight();
    double pWidth = format.getImageableWidth();

    double pXStart = format.getImageableX();
    double pYStart = format.getImageableY();

    double xRatio = pWidth / cWidth;
    double yRatio = pHeight / cHeight;


    Graphics2D g2 = (Graphics2D) g;
    g2.translate(pXStart, pYStart);
    g2.scale(xRatio, yRatio);
    comp.printAll(g2);

    return Printable.PAGE_EXISTS;
 }



}

你正在使用这行代码进行引用比较 if (preformat != postformat) { - user489041
@user489041 实际上,即使 if (!preformat.equals(postformat)) { 也可能不起作用,因为 PageFormat.hashCode() 没有被重写。此外,应该删除此语句,因为取消页面对话框意味着用户满意当前设置,打印对话框应该出现。 - Hummeling Engineering BV
仍然无法工作。删除 if (preformat != postformat) 后。 - Bhushan Gadekar
2个回答

1

打印Swing组件的简单方法:

/**
 * Create a BufferedImage for Swing components. The entire component will be
 * captured to an image.
 *
 * @param component Swing component to create image from
 * @return  image the image for the given region
 */
public static BufferedImage createImage(JComponent component)
{
    Dimension d = component.getSize();

    if (d.width == 0 || d.height == 0)
    {
        d = component.getPreferredSize();
        component.setSize(d);
    }

    Rectangle region = new Rectangle(0, 0, d.width, d.height);
    return ScreenImage.createImage(component, region);
}

/**
 * Create a BufferedImage for Swing components. All or part of the component
 * can be captured to an image.
 *
 * @param component Swing component to create image from
 * @param region The region of the component to be captured to an image
 * @return  image the image for the given region
 */
public static BufferedImage createImage(JComponent component, Rectangle region)
{
    //  Make sure the component has a size and has been layed out.
    //  (necessary check for components not added to a realized frame)

    if (!component.isDisplayable())
    {
        Dimension d = component.getSize();

        if (d.width == 0 || d.height == 0)
        {
            d = component.getPreferredSize();
            component.setSize(d);
        }

        layoutComponent(component);
    }

    BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = image.createGraphics();

    //  Paint a background for non-opaque components,
    //  otherwise the background will be black

    if (!component.isOpaque())
    {
        g2d.setColor(component.getBackground());
        g2d.fillRect(region.x, region.y, region.width, region.height);
    }

    g2d.translate(-region.x, -region.y);
    component.paint(g2d);
    g2d.dispose();
    return image;
}

 public int print(Graphics g, PageFormat pf, int i) throws PrinterException     {

    /*
     * User (0,0) is typically outside the imageable area, so we must
     * translate by the X and Y values in the PageFormat to avoid clipping
     */
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());

    //get the image to print
    BufferedImage theImage = createImage(/*your JPanel*/);


    double pageWidth = pf.getImageableWidth();
    double pageHeight = pf.getImageableHeight();
    double imageWidth = theImage.getWidth();
    double imageHeight = theImage.getHeight();
    double scaleX = pageWidth / imageWidth;
    double scaleY = pageHeight / imageHeight;
    double scaleFactor = Math.min(scaleX, scaleY);
    g2d.scale(scaleFactor, scaleFactor);
    g.drawImage(theImage, 0, 0, Color.WHITE, null);

    /* tell the caller that this page is part of the printed document */
    return PAGE_EXISTS;
}

但是如何将这段代码集成到我的代码中呢?因为你可以看到这些都是静态方法。:( - Bhushan Gadekar
它们应该是静态的,但不一定非得这样。只需将它们添加到您的类中即可。 - user489041
layoutComponent 方法是什么? - ryvantage
另外,你从哪里获取g来传递给print方法?? - ryvantage

0
  • Component.printAll(Graphics g)语句之前关闭双缓冲(但记得在之后恢复其状态)。

  • 此外,我建议使用相同的缩放因子来保持宽高比。

    double xyRatio = Math.min(pWidth / cWidth, pHeight / cHeight);
    
  • 添加一些日志记录或System.out.println(String)语句以缩小问题范围!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接