How can I print a custom paper size (cheques 8" x 4")?

23,473

Printing is designed to work in pixels per inch. The base print API uses a DPI of 72.

You need to convert your measurements accordingly...

double paperWidth = 8 * 72d;
double paperHeight = 4 * 72d;
double margin = 1 * 72d;

UPDATED with example

g2d.setClip(0, 0, (int)pageFormat.getImageableWidth(), (int)pageFormat.getImageableHeight()); is ill adviced, dangerous and generally, not required, besides which, you've used the wrong width and height values. The imageable parameters take into account the margins, but you've not translated the graphics, which will more then likely cut of the bottom, left portion of the area you do have to print to...

I'd just avoid using clipping

enter image description here

public class TestPrinting01 {

    public static void main(String[] args) {

        PrinterJob pj = PrinterJob.getPrinterJob();
        if (pj.printDialog()) {
            PageFormat pf = pj.defaultPage();
            Paper paper = pf.getPaper();
            double width = 8d * 72d;
            double height = 4d * 72d;
            double margin = 1d * 72d;
            paper.setSize(width, height);
            paper.setImageableArea(
                    margin,
                    margin,
                    width - (margin * 2),
                    height - (margin * 2));
            System.out.println("Before- " + dump(paper));
            pf.setOrientation(PageFormat.LANDSCAPE);
            pf.setPaper(paper);
            System.out.println("After- " + dump(paper));
            System.out.println("After- " + dump(pf));
            dump(pf);
            PageFormat validatePage = pj.validatePage(pf);
            System.out.println("Valid- " + dump(validatePage));

            Book pBook = new Book();
            pBook.append(new Page(), pf);
            pj.setPageable(pBook);

            try {
                pj.print();
            } catch (PrinterException ex) {
                ex.printStackTrace();
            }
        }
    }

    protected static String dump(Paper paper) {
        StringBuilder sb = new StringBuilder(64);
        sb.append(paper.getWidth()).append("x").append(paper.getHeight())
                .append("/").append(paper.getImageableX()).append("x").
                append(paper.getImageableY()).append(" - ").append(paper
                .getImageableWidth()).append("x").append(paper.getImageableHeight());
        return sb.toString();
    }

    protected static String dump(PageFormat pf) {
        Paper paper = pf.getPaper();
        return dump(paper);
    }

    public static class Page implements Printable {

        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
            if (pageIndex >= 1) {
                return Printable.NO_SUCH_PAGE;
            }

            Graphics2D g2d = (Graphics2D) graphics;
            // Be careful of clips...
            g2d.translate((int) pageFormat.getImageableX(), (int) pageFormat.getImageableY());

            double width = pageFormat.getImageableWidth();
            double height = pageFormat.getImageableHeight();

            g2d.drawRect(0, 0, (int)pageFormat.getImageableWidth() - 1, (int)pageFormat.getImageableHeight() - 1);
            FontMetrics fm = g2d.getFontMetrics();
            String text = "top";
            g2d.drawString(text, 0, fm.getAscent());

            text = "bottom";
            double x = width - fm.stringWidth(text);
            double y = (height - fm.getHeight()) + fm.getAscent();
            g2d.drawString(text, (int)x, (int)y);

            return Printable.PAGE_EXISTS;
        }
    }
}

UPDATED

When printing components, you become responsible for it's layout.

enter image description here

public class TestPrinting01 {

    private static JEditorPane editor;

    public static void main(String[] args) {

        try {

            editor = new JEditorPane();
            editor.setPage(new File("C:/hold/search.htm").toURI().toURL());

            PrinterJob pj = PrinterJob.getPrinterJob();
            if (pj.printDialog()) {
                PageFormat pf = pj.defaultPage();
                Paper paper = pf.getPaper();
                double width = 8d * 72d;
                double height = 4d * 72d;
                double margin = 1d * 72d;
                paper.setSize(width, height);
                paper.setImageableArea(
                        margin,
                        margin,
                        width - (margin * 2),
                        height - (margin * 2));
                System.out.println("Before- " + dump(paper));
                pf.setOrientation(PageFormat.LANDSCAPE);
                pf.setPaper(paper);
                System.out.println("After- " + dump(paper));
                System.out.println("After- " + dump(pf));
                dump(pf);
                PageFormat validatePage = pj.validatePage(pf);
                System.out.println("Valid- " + dump(validatePage));

                Book pBook = new Book();
                pBook.append(new Page(), pf);
                pj.setPageable(pBook);

                try {
                    pj.print();
                } catch (PrinterException ex) {
                    ex.printStackTrace();
                }
            }

        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }

    protected static String dump(Paper paper) {
        StringBuilder sb = new StringBuilder(64);
        sb.append(paper.getWidth()).append("x").append(paper.getHeight())
                .append("/").append(paper.getImageableX()).append("x").
                append(paper.getImageableY()).append(" - ").append(paper
                .getImageableWidth()).append("x").append(paper.getImageableHeight());
        return sb.toString();
    }

    protected static String dump(PageFormat pf) {
        Paper paper = pf.getPaper();
        return dump(paper);
    }

    public static class Page implements Printable {

        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
            if (pageIndex >= 1) {
                return Printable.NO_SUCH_PAGE;
            }

            Graphics2D g2d = (Graphics2D) graphics;
            // Be careful of clips...
//            g2d.setClip(0, 0, (int) pageFormat.getWidth(), (int) pageFormat.getHeight());
            g2d.translate((int) pageFormat.getImageableX(), (int) pageFormat.getImageableY());

            double width = pageFormat.getImageableWidth();
            double height = pageFormat.getImageableHeight();

            System.out.println("width = " + width);
            System.out.println("height = " + height);

            editor.setLocation(0, 0);
            editor.setSize((int)width, (int)height);
            editor.printAll(g2d);

            g2d.setColor(Color.BLACK);
            g2d.draw(new Rectangle2D.Double(0, 0, width, height));

            return Printable.PAGE_EXISTS;
        }
    }
}
Share:
23,473
Liam
Author by

Liam

Updated on November 28, 2020

Comments

  • Liam
    Liam over 3 years

    I am trying to print a custom paper size from a Java applet. I have set the paper size but it is being ignored.

    I have also tried using the book method as I have seen something about this helping to get it working but when I use that it just prints a blank page and still seems to be about A4 (I'm looking to print cheques which are obviously much smaller (8" x 4")).

    I am trying to print HTML from a JEditorPane if that makes any difference.

    If you have any ideas I would be very grateful, I'm tearing my hair out with this one.

    I should also add that I am very much a beginner when it comes to Java.

    Here is what I have so far:

    Updated: I have now got the page size right but can't seem to get the HTML page I'm loading to fit or line up with the page size.

    Update: Now I just can't get the applet to run in the browser. It works from eclipse just not the browser. I will also need to pass the URL from a parameter.

    Here is the HTML applet tag I'm using and updated Java code:

    <!DOCTYPE html>
    <html>
    <head><title>Printing Cheque</title></head>
    <body>
    <applet width=100 height=100 code="HTMLPrinter"
            archive="cheque_print.jar">
    </applet>
    
    </body>
    </html>
    
    
    package com.yunatech.pns.chequeprint;
    
    import java.applet.Applet;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.print.Book;
    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 javax.swing.JEditorPane;
    
    public class HTMLPrinter extends Applet {
    
        /**
         * 
         */
        private static final long serialVersionUID = 8065834484717197790L;
        private static JEditorPane editor;
    
        public HTMLPrinter() {
    
    
            try {
    
                editor = new JEditorPane();
                editor.setPage("http://localhost/print_test/test.html");
    
                PrinterJob pj = PrinterJob.getPrinterJob();
                if (pj.printDialog()) {
                    PageFormat pf = pj.defaultPage();
                    Paper paper = pf.getPaper();
                    double width = 8d * 72d;
                    double height = 4d * 72d;
                    double margin = 1d * 72d;
                    paper.setSize(width, height);
                    paper.setImageableArea(
                            margin,
                            0,
                            width - (margin * 2),
                            height);
                    System.out.println("Before- " + dump(paper));
                    pf.setOrientation(PageFormat.PORTRAIT);
                    pf.setPaper(paper);
                    System.out.println("After- " + dump(paper));
                    System.out.println("After- " + dump(pf));
                    dump(pf);
                    PageFormat validatePage = pj.validatePage(pf);
                    System.out.println("Valid- " + dump(validatePage));
    
                    Book pBook = new Book();
                    pBook.append(new Page(), pf);
                    pj.setPageable(pBook);
    
                    try {
                        pj.print();
                    } catch (PrinterException ex) {
                        ex.printStackTrace();
                    }
                }
    
            } catch (Exception exp) {
                exp.printStackTrace();
            }
        }
    
        protected static String dump(Paper paper) {
            StringBuilder sb = new StringBuilder(64);
            sb.append(paper.getWidth()).append("x").append(paper.getHeight())
                    .append("/").append(paper.getImageableX()).append("x").
                    append(paper.getImageableY()).append(" - ").append(paper
                    .getImageableWidth()).append("x").append(paper.getImageableHeight());
            return sb.toString();
        }
    
        protected static String dump(PageFormat pf) {
            Paper paper = pf.getPaper();
            return dump(paper);
        }
    
        public static class Page implements Printable {
    
            public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
                if (pageIndex >= 1) return Printable.NO_SUCH_PAGE;
    
                Graphics2D g2d = (Graphics2D)graphics;
                g2d.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());
    
                editor.setSize((int)pageFormat.getImageableWidth(), (int)pageFormat.getImageableHeight());
                editor.print(g2d);
    
                return Printable.PAGE_EXISTS;
            }
        }
    }
    

    Thanks in advance for any help you can offer.

  • Liam
    Liam over 11 years
    Thanks for the reply but this didn't seem to change anything. Still good to know if I can get it to accept my paper size.
  • Liam
    Liam over 11 years
    Thanks, that helped a lot and I am a lot closer to getting what I want. The Paper size is correct but I can't seem to get the HTML page I'm loading the right size or position. I have updated the code above to show what I now have. Any ideas where I'm going wrong?
  • MadProgrammer
    MadProgrammer over 11 years
    About the only thing I can identify is that fact that I set the components position, but I don't have your HTML file ;)
  • Liam
    Liam over 11 years
    Thanks very much for your help. I am now using a mixture of what you showed me and some of what I had. My only issue now is running it as an applet in the browser. I will update my post with what I have now. I will also mark your help as the answer. You have been a life saver already. Thanks
  • MadProgrammer
    MadProgrammer over 11 years
    Printing may be within the protected domain of restricted actions. This may prevent the applet from begin allowed to print unless it has the required security access as supplied by the clients applet.policy