Improve company productivity with a Business Account.Sign Up


java.awt.print VS javax.print

Posted on 2004-04-16
Medium Priority
2 Endorsements
Last Modified: 2012-08-14
Hello everyone,

I have to create a class that will print out a document that has a barcode (graphic) in it. This document will be created in the code (don't know which type of object yet) and does not come from the HD (maybe this makes a difference, i don't know).

I've been reading about different ways to acheive this and found that there are many packages that offer printing possibilities.

My question is, what's the main difference between JAVA.AWT.PRINT and JAVAX.PRINT ? Which one would be best ?

Question by:mariec
  • 5
  • 4

Author Comment

ID: 10856981
Points increased.

Author Comment

ID: 10866911
since nobody seems to really know this, are there any examples of how to print some text with some images? Is it possible to format the elements on a page ?


Accepted Solution

johnknapp earned 800 total points
ID: 10867304
Well, they are not really one or the other,

javax.print.* and it supplimentary packages are for printer communications, i.e. getting the available printers, querying printer functionality, and sending print jobs, listening to print jobs, among other things

java.awt.print is used for the print code The code that generates the printing

Here is how I usuall incorporate my printing (there is some extra stuff in here, but this is also a complicated topic)

i usually start out with a base class, just to supply basic printing params and gives me a canvas to draw on

public class AbstractPrintableDocument extends JComponent implements PrintableDocument {

    protected String documentName;

    public AbstractPrintableDocument() {

    public DocPrintJob getPrintJob(PrintService ps) throws NullPointerException {
        return (ps.createPrintJob());
    public PrintRequestAttributeSet getPrintRequestAttributeSet() {
        return (null);
    public Doc getDoc() {
        return (null);
    public void print(PrintService ps) throws PrintException {}

    public void addPrintJobListener(PrintJobListener l) {}
    public void removePrintJobListener(PrintJobListener l) {}    

    public int print(java.awt.Graphics graphics, java.awt.print.PageFormat pageFormat, int pageIndex) {
        return (NO_SUCH_PAGE);

    public void setDocumentName(String documentName) {
        this.documentName = documentName;


and then override that with something useful like ...

public class Cheshire2UpPrintableDocument extends AbstractPrintableDocument {

    private static final boolean debug = true;

    private Dimension dimension;

    private PrintRequestAttributeSet set;
    private Font defaultFont;
    private Doc doc;

    private int currentPage = 0;

    private PrintRecord[] records;

    private int totalPages = 0;

    private Paginator paginator;

    private boolean paginated = false;

    private String dateString;

    public Cheshire2UpPrintableDocument() {
        set = _getPrintRequestAttributeSet();
        doc = _getDoc();
        dateString = _getDateString();
        defaultFont = _getDefaultFont();
        dimension = new Dimension(612, 792);
        records = new PrintRecord[0];
        paginator = new Paginator(8);
    private String _getDateString() {
        java.util.Date d = new java.util.Date(System.currentTimeMillis());
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("MM/dd/yyyy");
        String s = format.format(d);
        return (s);

    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) { // here is the java.awt.print.Printable implementation
        if (!paginated)
            paginate((Graphics2D) graphics);
        if (pageIndex < totalPages) {
            currentPage = pageIndex;
            status("Page Index At Print: " + pageIndex);
            return (PAGE_EXISTS);
        } else {
            return (NO_SUCH_PAGE);

    public PrintRequestAttributeSet getPrintRequestAttributeSet() { return (set); }

    protected PrintRequestAttributeSet _getPrintRequestAttributeSet() { // tells the printer what my document will require
        PrintRequestAttributeSet mset = new HashPrintRequestAttributeSet();
        mset.add(new JobName((documentName != null ? documentName : "Cheshire 2 Up Document"), null));
        MediaPrintableArea area = new MediaPrintableArea(.5f, .5f, 7.5f, 10f, MediaPrintableArea.INCH);
        return (mset);    
    protected Doc _getDoc() {
        Doc mdoc = new SimpleDoc(this,
        return (mdoc);

    public Doc getDoc() { return (_getDoc()); }

    protected Font _getDefaultFont() {
        javax.swing.JTextField field = new javax.swing.JTextField();
        Font font = field.getFont();
        font = font.deriveFont(Font.PLAIN, 10f); // 10's gotta work
        font = Font.getFont("Arial", font);
        font.deriveFont(Font.PLAIN, 10f);
        if (debug) System.out.println("Cheshire2UpPrintableDocument Default Font Is: " + font.getName());
        return (font);

    public Dimension getMaximumSize() { return (dimension); }
    public Dimension getMinimumSize() { return (dimension); }
    public Dimension getPreferredSize() { return (dimension); }
    public void setPrintRecords(PrintRecord[] recs) { // sets the records this document will print
        records = new PrintRecord[recs.length];
        System.arraycopy(recs, 0, records, 0, records.length);
        if (debug) System.out.println(getClass().getName() + " setPrintRecords " + records.length);
    public void setPrintRecords(ExportRecord[] exRecs) {
        Vector temp = new Vector();
        for (int i = 0; i < exRecs.length; i++) {
        Object[] arr = temp.toArray();
        PrintRecord[] recs = new PrintRecord[arr.length];
        System.arraycopy(arr, 0, recs, 0, arr.length);
    protected void paginate(Graphics2D g) {
        paginator.setRecords(records); // paginator is a utility class to split pages based off the number of records
        totalPages = paginator.getPages();
        paginated = true;
    protected void paintComponent(Graphics g) { // overriden to paint the document
        paintDocument((Graphics2D) g);
    protected void paintDocument(Graphics2D g) {

        status("finished painting background");

        status("start pagination");

        if (!paginated)

        status("finished pagination");


        g.translate(36, 36);
        status("finished translation");
        status("getting records");
        Object[] temp = paginator.getRecordsByPage(currentPage);    
        PrintRecord[] recs = new PrintRecord[temp.length];
        System.arraycopy(temp, 0, recs, 0, recs.length);
        status("finished records");
        if (debug) System.out.println("From Paginator on page " + currentPage + " recs " + recs.length);
        int recPos = 0;
        status("starting to paint records");
        for (int rows = 0; rows < 4; rows++) {
            for (int cols = 0; cols < 2; cols++) {
                PrintRecord rec = (recPos < recs.length ? recs[recPos] : null);
                paintRecord(g, rows, cols, rec);
        status("finished painting records");
    private void status(String msg) {
        if (debug) {
            System.out.println(getClass().getName() + ": " + msg);
    protected void paintRecord(Graphics2D g, int row, int col, PrintRecord rec) {
        if (rec == null)
        if (debug) System.out.println("Printing Record " + row + " " + col);
        Point2D point = translate(row, col);
        status("paintRecordAt(" + row + ", " + col + ")");
        FontRenderContext frc = g.getFontRenderContext();
        TextLayout layout = null;
        String[] lines = prepareRecord(rec);
        float currentY = (float) point.getY();
        String ifNull = "ifNull";
        for (int i = 0; i < lines.length; i++) {
            if (lines[i] == null || lines[i].length() == 0) {
                layout = new TextLayout(ifNull, g.getFont(), frc);
                currentY += layout.getAscent();
                // layout.draw(g, (float) point.getX(), currentY);
                currentY += layout.getDescent() + layout.getLeading();
            } else {
                layout = new TextLayout(lines[i], g.getFont(), frc);
                currentY += layout.getAscent();
                layout.draw(g, (float) point.getX(), currentY);
                currentY += layout.getDescent() + layout.getLeading();
    protected String[] prepareRecord(PrintRecord rec) {
        Vector temp = new Vector();
        String firstRec = "NAME RECORD";
        firstRec += " ";
        firstRec += dateString;
        if (rec.getFullName() != null)
        if (rec.getCompanyName() != null)
        if (rec.getAddress() != null)
        if (rec.getCity() != null && rec.getState() != null && rec.getZip() != null)
        temp.add(formatPhone("Business", rec.getPrimaryPhone()));
        temp.add(formatPhone("Home", rec.getSecondaryPhone()));
        String add1 = rec.getAdditional1();
        String add2 = rec.getAdditional2();
        if (add1 != null)
        if (add2 != null)
        Object[] arr = temp.toArray();
        String[] s = new String[arr.length];
        System.arraycopy(arr, 0, s, 0, s.length);
        return (s);
    private String prepareCityStateZip(PrintRecord rec) {
        StringBuffer sb = new StringBuffer();
        sb.append(rec.getCity()).append(", ").append(rec.getState());
        sb.append(" ");
        return (sb.toString());
    protected Point2D translate(int row, int col) {
        Point2D point = new Point2D.Float();
        switch (row) {
            case 0: point.setLocation(0, 13.0000/40.0000); break;
            case 1: point.setLocation(0, 108.0000/40.0000); break;
            case 2: point.setLocation(0, 203.0000/40.0000); break;
            case 3: point.setLocation(0, 298.0000/40.0000); break;
        switch (col) {
            case 0: point.setLocation(24.0000/40.0000, point.getY()); break;
            case 1: point.setLocation(174.0000/40.0000, point.getY()); break;
        Point2D act = new Point2D.Double((point.getX() * 72), (point.getY() * 72));
        status("Returning Point: " + act.getX() + ", " + act.getY());
        return (act);

    private String formatPhone(String title, String phone) {
        if (phone == null || phone.length() == 0)
            return (title + ":");
        StringBuffer sb = new StringBuffer();
        char[] arr = phone.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            appendIfNumeric(sb, arr[i]);
        String num = sb.toString();
        sb.append(": ");
        if (num.length() == 10) {
            sb.append(num.substring(0, 3));
            sb.append(") ");
            sb.append(num.substring(3, 6));
            sb.append(num.substring(6, 10));
        return (sb.toString());
    private String formatZip(String zip) {
        if (zip == null || zip.length() == 0)
            return ("");
        StringBuffer sb = new StringBuffer();
        char[] arr = zip.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            appendIfNumeric(sb, arr[i]);
        zip = sb.toString();
        if (zip.length() == 9) {
            sb.append(zip.substring(0, 5));
            sb.append(zip.substring(5, zip.length()));
            return (sb.toString());
        } else {
            return (zip);

    private void appendIfNumeric(StringBuffer sb, char c) {
        switch (c) {
            case '0': sb.append(c); return;
            case '1': sb.append(c); return;
            case '2': sb.append(c); return;
            case '3': sb.append(c); return;
            case '4': sb.append(c); return;
            case '5': sb.append(c); return;
            case '6': sb.append(c); return;
            case '7': sb.append(c); return;
            case '8': sb.append(c); return;
            case '9': sb.append(c); return;
            default: return;

    protected void paintBackground(Graphics2D g) {
        Rectangle2D rect = new Rectangle2D.Float(0f, 0f, dimension.width, dimension.height);

Anyway, sorry about verboseness the document prints 8 address records 4 * 2 4 rows, 2 columns

The code which is prints this document is fairly simple The complexity is kept in the printable document

    protected void printData() {
        final Cheshire2UpPrintableDocument dbs = new Cheshire2UpPrintableDocument();
        dbs.setPrintRecords(records); // obtained in another part of the code
        final PrinterJob job = PrinterJob.getPrinterJob(); // gets a printer job to create a print dialog
        boolean res = job.printDialog(dbs.getPrintRequestAttributeSet());  // returns true if user said yes to printing
        if (res) {
            final PrintService ps = job.getPrintService(); // gets the users chosen printer
            Runnable r = new Runnable() {
                public void run() { // always run print code in sep thread, since it is generally pretty time consuming
                    try {
                        DocPrintJob jarb = ps.createPrintJob();
                        jarb.print(dbs.getDoc(), dbs.getPrintRequestAttributeSet());
                    } catch (Exception e) {
            Thread t = new Thread(r);
        } else {

So, the java.awt.print.* package is still generally the workhorse responisble for actual formatting and printing

while the javax.print.* packages are used to get the print data to the correct printer with the correct parameters.

Hope This Helps,
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.


Author Comment

ID: 10867754
Thanks, this looks like what i needed.

Is the PrintableDocument interface from the com.davidflanagan.examples.print package? If not, does is implement Pageable and Printable anyway?

Assisted Solution

johnknapp earned 800 total points
ID: 10869446
Sorry, I should have posted that also:

It isn't from the com.davidflanagan.examples.print package, but the idea of it was taken from that among other sources . . . here is the code for PrintableDocument

package com.asymm.listman.shared;

import java.awt.print.Printable;

import javax.print.PrintService;
import javax.print.DocPrintJob;
import javax.print.Doc;
import javax.print.PrintException;

import javax.print.attribute.PrintRequestAttributeSet;

import javax.print.event.PrintJobListener;

public interface PrintableDocument extends Printable  {

     * Gets a doc print job to print with the appropriate parameters set
     * @param ps The print service to print the job to
     * @return A doc print job object to print
     * @exception java.lang.NullPointerException if print service parameter is null
    public DocPrintJob getPrintJob(PrintService ps) throws NullPointerException;

     * Gets the print request attribute set that this printable document will use
     * @return A print request attribute set with appropriate parameters set
    public PrintRequestAttributeSet getPrintRequestAttributeSet();

     * Get doc that this will use internally
     * @return The doc
    public Doc getDoc();    

     * Handles all printing for this document
     * @param ps The print service to print to
     * @exception javax.print.PrintException If an underlying print exception occurs
    public void print(PrintService ps) throws PrintException;    

    public void addPrintJobListener(PrintJobListener l);
    public void removePrintJobListener(PrintJobListener l);

    public void setDocumentName(String documentName);


Sorry about not posting that again,

It has been a while since I went that deep into it again, I ususally just extend AbstractPrintableDocument for the stuff since for this current project with some 20+ printables and another 7 faxables I am trying to cut down on my work as much as possible.


Assisted Solution

johnknapp earned 800 total points
ID: 10869517
Also, sorry I forgot about printing images . . . but this is esentially how I do it

     * Draws the logo
     * @param g The graphics 2d object to draw on
     * @see #drawSalesOrder
    protected void drawLogo(Graphics2D g) {
        BufferedImage li = getLogoImage();
        if (li == null) {
        } else {
            g.scale(.125, .125);
            g.drawImage(li, null, 0, 0);
            g.scale(8, 8);
            ypos = li.getHeight();

    /** Gets the logo image specified in the logoFile */
    private BufferedImage getLogoImage() {
        BufferedImage logoImage = null;
        try {
            logoImage =;
            if (debug) System.out.println("Successfully Read in Image File");
        } catch (Exception e) {
            if (debug) System.out.println(e);
        return (logoImage);

The reason I scale down first by 8 is that the image is 8 times the size I want it to be . . . I did this since when I printed the normal size image at the 72 pixels / inch it printed kind of poor - some banding on the image, my printer prints at a higher res so I sized up the image so that there are more pixels per inch and it looks great.  Just remember to scale back to normal, since setting the scale on graphics will continue to keep it that scale until set to something else.

I hope that also helps.  Generally for my complicated printables they get pretty long 1000+ lines of code . . .

You can also look into generating from apache fop . . . to create adobe acrobat documents and print those after they are created.  This can help if you will eventually be faxing the same printables, or emailing pdfs.

Expert Comment

ID: 10869533
By The By,

where did you get the info on the bar code stuff, which bar code is it? I have a client in which I had to use a third party software package for bar coding . . . I couldn't find the open standards, except for the really simple barcodes . . .

Expert Comment

ID: 10869665
Oh and I also forgot,

If you want to print without user intervention and send the stuff to a chosen printer directly, you can bypass the whole print dialog with code similar to the following

Cheshire2UpPrintableDocument cheshDoc = new Cheshire2UpPrintableDocument(); // pretend already initialized

PrintService[] services = PrintServiceLookup.lookupPrintServices(DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);

 * I have a client properties thing where I keep a default printer stored, and then get the correct print service this way
String dpName = ClientProperties.getString("defaultprinter", null); // gets the value specified by key defaultprinter, with null as a backup value if not found
PrintService defaultPrintService = null;
if (dpName == null) {
    // tell client no dp printer chosen
} else {
    for (int i = 0; i < services.length; i++) {
        if (serivces[i].getName().equals(dpName))
            defaultPrinterService = services[i];

if (defaultPrinterService == null) {
    // warn user could not find default printer -maybe disconnected ? or name changed? have them rechoose

try {
    cheshDoc.print(defaultPrinterService); // or whichever one matches the criteria
} catch (Exception e) {
    // handle print exception

Author Comment

ID: 10870320
I doubled points because this is very helpful and more than I was expecting!

The barcode stuff comes from a third party package ( that our client gave us for developing their solution. Usually it is distributed as a package but they got the source code and in it is says that it can be modified for our needs. There are many standards included.

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
The viewer will learn how to implement Singleton Design Pattern in Java.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

608 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question